parabellym, threaded mode
Justin Forest <[email protected]> Thu, 15 Apr 2004 17:33:50 +0400
| Newsgroups | gmane.comp.misc.faerion.devel |
|---|---|
| Message-ID | <[email protected]> |
Некоторые мысли относительно работы модулей в parabellym.
Напомню, изначально планировалось, что модуль:
1) загружается,
2) инсталлирует обработчики сообщений,
3) выгружается.
При таком раскладе возникают две проблемы:
1) Все модули работают в рамках одного потока. Собственно, вся система
работает в одном потоке. В его контексте и вызываются все обработчики
сообщений. Собственно, проблема: модули работают в полностью
асинхронном режиме, т.е. работа производится исключительно обработчиками
сообщений. Никакой личной жизни. Для того, чтобы выполнять задачи,
происходящие в фоновом режиме, нужно периодически кричать эхом.
2) Небезопасно. Один поток == один стэк, один модуль искривился -- вся
система рухнула.
Отсюда возникла идея выполнения каждого модуля в рамках отдельного
потока. Вместо двух init/fini функций модуль экспортирует одну:
body[1], которой производит инициализацию, входит в цикл приёма
сообщений, когда надоедает -- выходит из функции, что является сигналом
к выгрузке модуля системой.
Меняется схема обработки сообщений: они теперь не приходят в пассивном
режиме, через обратные вызовы, а целенаправленно принимаются, вызовом
специальной функции. При этом можно ограничить время ожидания
сообщения, таким образом получив время для "личной жизни" (т.е. для
этого теперь не нужно ждать сигнала извне).
Для фильтрации получаемых модулем сообщений их, как и раньше, нужно
сперва запросить. Однако если раньше этот процесс сопровождался
инсталляцией обратного вызова, то теперь это простая функция,
принимающая имя сообщения, и возвращающая его идентификатор [2].
Идентификатор сохраняется и в дальнейшем используется для сравнения при
получении сообщения [3].
Неявное отличие: модуль теперь нельзя насильно выгрузить. Для этого
пришлось бы убить поток, прервав нормальный ход программы, что
потенциально ведёт к утечкам памяти. Кроме того возникает вопрос об
ограничении доступа к функции выгрузки, что является дополнительной
лишней заморочкой. Теперь же модуль можно вежливо попросить выйти,
послав соответствующее сообщение (формат ещё предстоит обдумать).
Модуль может не захотеть выгружаться, тогда он просто игнорирует это
сообщение и остаётся работать дальше.
В многопоточной среде также проще "усыпить" модуль до получения ответа
на отправленное сообщение с двунаправленными параметрами. В
однопоточной среде реализация была бы достаточно сложной и кривой.
Изменение схемы работы модулей таким образом существенно облегчает
построение распределённых парабеллумов, а на ныне существующих модулях
почти никак не сказывается: изменения, вносимые в код, будут минимальными.
Комментарии.
1. void para_modbody(void);
При выходе из процедуры система деинсталлирует все запрошенные
модулем сообщения и выгружает сам модуль.
2. int para_install_message(const char *msgname);
В случае ошибки возвращает (отрицательный) код ошибки, в случае
успеха -- код, присвоенный сообщению. С этого момента модуль
будет получать такие сообщения.
Если в системе уже зарегистрировано сообщение с указанными
именем, возвращается идентификатор уже существующего, новое
сообщение не создаётся. Исключение составляют случаи, когда
параметр msgname равен нулю (он же NULL): в таком случае всегда
будет создано новое сообщение с уникальным идентификатором.
Использовать предполагается для обратных вызовов в случае, если
модуль хочет получать ответы на свои сообщения асинхронно.
3. Пример:
int msgid = para_install_message("test"), rcvd;
while ((rcvd = para_receive_message(&argc, &argv)) > 0) {
if (rcvs == msgid) {
// обрабатываем сообщение "test"
}
}
-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
-------------------------------------------------------
Discussions in this list are held in two languages: English and Russian.
When replying, please use the language that the sender of the original
message is guaranteed to understand, or use English.