![]() |
|
Модераторы: xvr |
![]()
|
|
| fish9370 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 15.4.2007 Где: Москва Репутация: 2 Всего: 1 |
Здравствуйте,
есть задача: 1. принять сообщение 2. передать сообщение модулю по префиксу команды (к примеру команда monitor::update, где monitor - имя модуля, в котором находится обработчик, update - команда) 3. в заданном модуле произвести обработку, и асинхронно вернуть результат, в некоторую очередь в первом модуле пояснение к задаче: 1) за прием и маршрутизацию команд отвечает модуль router 2) тестовый модуль, в котором будет обработчик назовем monitor 3) при загрузке модуль monitor регистрирует функцию обработчик в модуле router. Добавляет в список префиксов префикс 'monitor' - связка префикс-обработчик 4) очередь результатов, находится в модуле router и должна быть доступна всем прочим модулям вопрос по 4 пункту: используется динамическое связывание, модули подключаются во время исполнения программы, как сделать объект общим? Если я описываю, объект как extern при связывании линкер пишет undefined symbol, если я не указываю extern создается локальная копия обоснованная критика архитектуры приветствуется -------------------- undefined |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 20 Всего: 223 |
Модуль router оформляется как librouter.so файл (с описанием объекта без каких либо префиксов в нем самом и с extern в соответствующем *.h файле) Главная программа линкуется с librouter.so, с ним же ликуются при компиляции все остальные загружаемые модули (они должны быть собраны в виде *.so файлов). Тогда при загрузке этих *.so (через dlopen) они подхватят librouter.so, который к тому времени уже будет загружен в основной программе Это сообщение отредактировал(а) xvr - 9.11.2014, 13:39 |
|||
|
||||
| Cheloveck |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1578 Регистрация: 26.7.2008 Где: Тула Репутация: нет Всего: 32 |
Описан dbus
-------------------- ![]() |
|||
|
||||
| svlary |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 207 Регистрация: 8.9.2009 Репутация: 4 Всего: 4 |
А почему нельзя воспользоваться СТАНДАРТНЫМ механизмом очередей сообщений в Linux? - man 2 msgget - man 3 mq_open Это база. Можно воспользоваться d-Bus, если хочется поковыряться... Просто, дело в том, что реализуя механизм очередей сообщений самостоятельно, Вы неизбежно столкнётесь с проблемой блокировок и анализом полноты буферов. Это не очень простые задачи. |
|||
|
||||
| fish9370 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 15.4.2007 Где: Москва Репутация: 2 Всего: 1 |
наверно можно, но это будет менее эффективно, все-таки msgget это механизм IPC. А так же, после, все-равно придется выполнять копирование в тот самый объект (хеш-таблица), так как с ним ведется работа dbus - тоже IPC это предусмотрено в самой хеш-таблице, там коллизии разрешаются списками, а списки лочатся. Это и сейчас работает, я просто уперся в архитектуру (модуль стал слишком жирным), мне нужно произвести эти изменения, чтобы двигаться дальше Добавлено @ 15:51 спасибо за ответ. но мне очень не хочется линковаться с еще одной либой, дело в том, что модули выгружаемые, и совсем не факт, что во всех конфигурациях это понадобится - в некоторых случаях она будет висеть мертвым грузом я не понимаю, почему ld не может его слинковать с глобальным символом, если он находится в модуле router.so и грузится раньше остальных. Он же глобальный Это сообщение отредактировал(а) fish9370 - 10.11.2014, 15:59 -------------------- undefined |
|||
|
||||
| tzirechnoy |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1173 Регистрация: 30.1.2009 Репутация: 3 Всего: 16 |
Описан любой message oriented middleware. То есть вообще любой, от zeromq до CORBA/WebSphere. И совершэнно необязательно брать сразу самый дебильно сделанный. |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 20 Всего: 223 |
Может, именно это я и предлагал. А что бы на этапе сборки линкер не ругался, ему этот router.so надо подать в линковку (при сборке модулей/динамических библиотек). |
|||
|
||||
| Guinness |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 21.6.2009 Где: Зеленоград Репутация: нет Всего: 10 |
А почему самый дебильный? Я просто его использовал в связке с Qt, не скажу, что получал удовольствие, скорее наоборот, но оно работало. Потом пытался найти какую-то межхостовую его замену и наткнулся на ZeroC Ice. По описанию понравилось, даже написал тестовый примерчик Python vs C++. К несчастью времени попользовать его в боевых условиях не хватило. Приведённые Вами лучше или каждый хорош по своему? |
|||
|
||||
| fish9370 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 15.4.2007 Где: Москва Репутация: 2 Всего: 1 |
я попробую поиграться в разделе описания, раньше у меня таких проблем не было мне нужно было выговориться, слишком я долго носил это в себе -------------------- undefined |
|||
|
||||
| tzirechnoy |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1173 Регистрация: 30.1.2009 Репутация: 3 Всего: 16 |
<quote>>Если я описываю, объект как extern при связывании линкер пишет undefined symbol,</quote>
1) Ни в коем случае, никогда, never, nie, nunca, jamais -- не делай глобальных объектов. И синглтонов тожэ не делай. Когда тебе будет можно -- ты ужэ прекрасно поймёшь, о чём я, и что я имел в виду, а пока не понял -- просто не делай. 2) Типичный -- вызываешь какую-нибудь функцыю init(), или connect("address") которая возвращает ссылку на нужный тебе объект. У объекта, если он действительно объект C++ -- хорошым тоном будет сделать какой-нибудь абстрактный предок, с несколькими чисто виртуальным функцыями. А если не C++, с простой C -- то, соответственно, можно сделать непрозрачную структуру, которая просто передаётся внутрь функцый библиотеки-мессенджэра. |
|||
|
||||
| svlary |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 207 Регистрация: 8.9.2009 Репутация: 4 Всего: 4 |
Разумеется. А в чём дело? Вы ведь писали:
Асинхронными могут быть только процессы (потоки/нитки). Иначе вся эта затея теряет смысл. Если изначально предполагалась многопоточность, т о почему же не использовать стандартные средства синхронизации?! Добавлено через 10 минут и 43 секунды
Для того, что бы ответить на этот вопрос, необходимо:
|
||||
|
|||||
| tzirechnoy |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1173 Регистрация: 30.1.2009 Репутация: 3 Всего: 16 |
Не знаю, как-то куда в нём ни ткнёшь -- в publish/subscribe, в marshalling (с системой типов из VBA, зато с обязательным юникодом), в релизацыю сервера, в его конфиг, в реальную поддержку tcp/ip -- всё как-то очень половинчато сделано. При этом да, жыть можно -- да что там, я и на VBA писал, тожэ вполне себе язык программирования.
У каждого свои плюсы. У того жэ 0mq -- вообще не маршаллинга, всё относительно с очередями (впрочем, в dbus с очередями примерно такжэ) -- зато скорость высокая. У полувзрослых брокеров (rabbitMQ, например) -- много приятностей, вообще, на мой взгляд, из распространённого и подо все языки, rabbitMQ -- самый вменяемый вариант. Плюсов и возможностей совсем взрослых (webSphere той жэ) я пока не ощутил, но вполне допускаю, что отказоустойивость и интэроперабельность с джавой у них более на высоте. |
||||
|
|||||
| fish9370 |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 15.4.2007 Где: Москва Репутация: 2 Всего: 1 |
я не буду это комментировать, просто выражу свое несогласие
1) не С++ 2) непрозрачную структуру - это как? 3) может пора уже что-то с русским языком сделать? сколько Вас читаю, ничего у Вас не меняется разумеется потоков несколько, но разница, между передачей данных через IPC и напрямую существенна. Нужно ли это объяснять?
компилится с ключами -fPIC и -shared линукуется динамически Это сообщение отредактировал(а) fish9370 - 10.11.2014, 21:33 -------------------- undefined |
||||||||
|
|||||||||
| tzirechnoy |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1173 Регистрация: 30.1.2009 Репутация: 3 Всего: 16 |
Это структура, поля которой не опубликованы для кода, который её использует. То есть как в stdio (stdin/stdout) или много где ещё. Доступ внутрь имеет только библиотека, которая обеспечивает интэрфейс к ней. Да, передаётся обычно через указатель. |
|||
|
||||
| fish9370 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 15.4.2007 Где: Москва Репутация: 2 Всего: 1 |
как это должно помочь в моем вопросе? -------------------- undefined |
|||
|
||||
| tzirechnoy |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1173 Регистрация: 30.1.2009 Репутация: 3 Всего: 16 |
Тебе не потребуется вообще ничего объявлять для использующего её класса. Ни глобальных объектов, ни локальных, и дажэ думать над окончательным списком полей, изменение которого сломало бы бинарную совместимость. |
|||
|
||||
| fish9370 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 15.4.2007 Где: Москва Репутация: 2 Всего: 1 |
а пример можно? -------------------- undefined |
|||
|
||||
| svlary |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 207 Регистрация: 8.9.2009 Репутация: 4 Всего: 4 |
Не обязательно! Через IPC - проверено и надёжно. Напрямую - деревянный велосипед на треугольных колёсах. Это моё убеждение. Я не призываю Вас следовать ему... -) Добавлено через 7 минут и 20 секунд Весьма абстрактный ответ... Так как Вы не ответили на третий мой пункт:
то у меня возникло подозрение, что Вы просто забыли задать линкеру ключик -l (или -L) задающий эти самые so-шки. Я ошибаюсь ? |
||||
|
|||||
| fish9370 |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 15.4.2007 Где: Москва Репутация: 2 Всего: 1 |
проверено, надежно, но для другой задачи. IPC подразумевает, копирование в ядро, затем передачу (копирование обратно в юзерсейс), потом снова копирование уже в требуемую структуру. При этом занимаются ресурсы ядра для этой задачи это все не нужно, структура на расстоянии вытянутой руки, просто возьми, да положи
мне не совсем понятен вопрос, -l там не требуется, так как линковки с данными so-шками нет (линк происходит динамически). Модули прекрасно собираются, и работают
Это сообщение отредактировал(а) fish9370 - 11.11.2014, 16:53 -------------------- undefined |
||||||
|
|||||||
| svlary |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 207 Регистрация: 8.9.2009 Репутация: 4 Всего: 4 |
Линковка двух взаимодействующих модулей происходит ВСЕГДА. Иначе они не смогут взаимодействовать. Но эта линковка может быть двух типов:
Во втором случае программа, настраивающая неразрешённые ссылки (Динамический линкер) должна знать, ГДЕ искать эти самые точки, на которые нужно настроить неразрешённые ссылки. so-шки линкуются динаически. Поэтому, линкер должен знать, в какой so-шке какие точки входа наличествуют. Поэтому, динамический компоновщик Linux ведёт хэш точек входа во все известные ему so-шки. Что бы такой хэш можно было обновлять, установлено соглашение, что все so-шки располагаются в
Команда
заставляет линкер перестроить его хэш. Если so-шка расположена НЕ в стандартном месте, то её расположение должно быть задано явно, с помощью ключей -l или -L. |
|||
|
||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 20 Всего: 223 |
Не совсем так. Для задания нестандартного места для so в run-time используется ключ -rpath (или переменная окружения LD_LIBRARY_PATH). А ключи -i и -L используются на этапе линковки, что бы линкер вообще был в курсе, что при запуске программы нужно загружать данные so'ки, ну и что в них надо искать неразрешенные до сих пор имена.
Как раз нужно, что бы загружаемый модуль знал, где искать extern struct hashtable users; |
||||
|
|||||
| fish9370 |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 15.4.2007 Где: Москва Репутация: 2 Всего: 1 |
нет, Вы слишком категоричны. В моей практике, чаще всего так: имеется глобальный объект, допустим двунаправленный связанный список, который объявлен в ядре (ядре программы). Ядро грузит модуль (some-module.so) с помощью dlopen. Модуль при инициализации добавляет обработчики к этому глобальному списку. Последующие модули делают тоже самое. При этом непосредственно между собой модули не линкуются. А при необходимости выполнить код другого модуля, они обращаются к этому списку. В момент выгрузки, они удаляют свои обработчики из этого списка и на том их взаимодействие заканчивается. Вы понимаете, что это совсем другая практика, нежели та, что указываете Вы? пожалуйста, освежите знания man 3 dlopen
как раз нужен ключ -l? -l я не использую, поймите же наконец Это сообщение отредактировал(а) fish9370 - 12.11.2014, 11:47 -------------------- undefined |
||||||
|
|||||||
| Ihost |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 24 Регистрация: 14.9.2012 Репутация: нет Всего: нет |
Изначальная задача сформулирована не очень однозначно- все-таки на каком этапе необходимо получить связаывание объектов переменных- на раннем этапе при сборке исполняемого модуля, или же на позднем при осуществлении вызовов dl*()
Если речь идет о первом случае, то очевидно что Вы сразу должны указать целевую область связывания, объявить для нее локальный идентификатор псевдонима, а при запуске выставить корректный LD_LIBRARY_PATH Если речь о втором случае, о каком именном псевдониме для связывания вообще можно говорить?! Подключили в процессе исполнения, забрали необходимый объект, сделали ссылку с учетом структуры - или же включили соответствующий .h-файл
Ах да и чтобы не пришлось лишний раз проводить незабываемые минуты веселья с demangler'ом, сделайте в исходном модуле такую штукенцию
|
||||
|
|||||
| fish9370 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 15.4.2007 Где: Москва Репутация: 2 Всего: 1 |
да, Вы правильно меня поняли вариант хороший, но так хотелось обойтись без этого дело в том, что я не пользуюсь этой функцией, я отдал это на откуп самому модулю, который сам регистрирует общие объекты а тут я вообще хотел на халяву, как-то автоматом связать -------------------- undefined |
|||
|
||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 20 Всего: 223 |
Это мы поняли, и поэтому у вас и происходит это - И что бы этого не происходило, и надо подать в сборку модулей -l<router> (где librouter.so и содержит ваш struct hashtable users). Физически struct hashtable users останется там же, где и был (в librouter.so), а в модулях появится только ссылка на него (в виде имени библиотеки) и связывание с его экспортируемыми символами. |
|||
|
||||
| fish9370 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 663 Регистрация: 15.4.2007 Где: Москва Репутация: 2 Всего: 1 |
я вас понял, спасибо, возможно это поможет -------------------- undefined |
|||
|
||||
![]()
|
| Правила форума "С/С++: Программирование под Unix/Linux" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |