Как может выглядеть реализация шаблона "Наблюдатель" при условии, что есть единственный "Генератор" событий и слушатели, и что "Генератор" и каждый "Слушатель" -- отдельные потоки. Слушатели, понятно, дожидаются появления события, потом его обрабатывают (параллельно, насколько это возможно), потом "Генератор" как-то узнаёт, что событие обработано всеми "Слушателями" и может генерировать следующее...
Это же должен быть какой-то типовой шаблон (пожалуйста, без привязки к конкретным языкам и библиотекам и тем более без ссылок на подходящии готовые реализации -- меня интересует алгоритм), но я как-то не могу нигде увидеть. Предположим, что есть только счётные семафоры, других механизмов синхронизации потоков нет. Как? По-моему что-то типовое, но я в упор не вижу.
fk0> Как может выглядеть реализация шаблона "Наблюдатель" при условии, что есть единственный "Генератор" событий и слушатели, и что "Генератор" и каждый "Слушатель" -- отдельные потоки. Слушатели, понятно, дожидаются появления события, потом его обрабатывают (параллельно, насколько это возможно), потом "Генератор" как-то узнаёт, что событие обработано всеми "Слушателями" и может генерировать следующее...
fk0> Это же должен быть какой-то типовой шаблон (пожалуйста, без привязки к конкретным языкам и библиотекам и тем более без ссылок на подходящии готовые реализации -- меня интересует алгоритм), но я как-то не могу нигде увидеть. Предположим, что есть только счётные семафоры, других механизмов синхронизации потоков нет. Как? По-моему что-то типовое, но я в упор не вижу.
Думаю, что решение будет таким: есть семафор, сбрасывать его может только генератор, включать может только слушатель. Каждый слушатель в ответ на сообщение может включить семафор только один раз. Если семафор включен, слушатель ждет, пока он не сбросится. Генератор постоянно сбрасывает включенный семафор, а поскольку генератор знает, сколько у него слушателей, то посчитав, сколько раз был включен семафор, может сделать вывод, была ли реакция у всех слушателей на сообщение. Если я все правильно понял и если я ничего не перепутал, то это будет решением.
Здравствуйте, D14, Вы писали:
D14>Здравствуйте, McQuay, Вы писали:
MQ>>Генератор постоянно сбрасывает включенный семафор
D14>Активный цикл сбрасываний — не айс.
А какие варианты? Генератор все равно должен монитроить изменение состояний по условию задачи. Событий ведь он не получает?
Re: шаблон наблюдатель в многопоточной среде
От:
Аноним
Дата:
09.09.09 11:49
Оценка:
Здравствуйте, fk0, Вы писали:
fk0> Как может выглядеть реализация шаблона "Наблюдатель" при условии, что есть единственный "Генератор" событий и слушатели, и что "Генератор" и каждый "Слушатель" -- отдельные потоки. Слушатели, понятно, дожидаются появления события, потом его обрабатывают (параллельно, насколько это возможно), потом "Генератор" как-то узнаёт, что событие обработано всеми "Слушателями" и может генерировать следующее...
fk0> Это же должен быть какой-то типовой шаблон (пожалуйста, без привязки к конкретным языкам и библиотекам и тем более без ссылок на подходящии готовые реализации -- меня интересует алгоритм), но я как-то не могу нигде увидеть. Предположим, что есть только счётные семафоры, других механизмов синхронизации потоков нет. Как? По-моему что-то типовое, но я в упор не вижу.
У Таненбаума в книги "Современные операционные системы" есть раздел с названием "Барьеры". Там написано:
Некоторые приложения делятся на фазы, и существует правило, что процесс не может перейти в следующую фазу, пока к этому не готовы все остальные процессы. Этого можно добиться, разместив в конце каждой фазы барьер. Когда процесс доходит до барьера, он блокируется, пока все процессы не дойдут до барьера.
Конкретная реализация не представлена, но может сама идея чем-нибудь поможет. Например, "Генератор" может предоставлять операцию, которую вызывает "Слушатель", обработав событие. "Слушатель" может даже передавать ссылку на себя в качестве параметра операции, тогда "Генератор" может отслеживать своих "Слушателей", обработавших событие. Соответственно, он не отправит следующее событие, пока все "Слушатели" не справятся с предыдущим. Таким образом, "Генератор" выполняет роль барьера.
message acknowledgement?
...решается, например, обратным обсервером
к примеру так:
— при посылке publisher засыпает на семафоре и ждёт, когда клиенты (через коллбэк) семафор обнулят и разбудят паблишера.
— acknowledgement message-и от клиентов.
MQ>А какие варианты? Генератор все равно должен монитроить изменение состояний по условию задачи. Событий ведь он не получает?
Я, прямо скажем, не большой специалист в этом, думаю как-то так
void emit()
{
Mutex.lock();
for (int i=0;i<n;++i)
{
положить в очередь сообщений i-го потока сообщение для обработки.
с указателями на Mutex и WaitCondition
}
WaitCondition.wait(&Mutex);
Mutex.unlock();
}
Получатель события {
Полезная работа
Mutex.lock();
Уменьшить счетчик обработанных сообщений.
if (последний получатель) WaitCondition.wake();
Mutex.unlock();
}
Здравствуйте, D14, Вы писали:
MQ>>А какие варианты? Генератор все равно должен монитроить изменение состояний по условию задачи. Событий ведь он не получает?
D14>Я, прямо скажем, не большой специалист в этом, думаю как-то так
Ну и получили логику семафора (точнее, барьера), с использованием условных переменных. Можно ту же логику семафора реализовать хоть на очередях сообщений.
Вопрос лишь в том, какой базис примитивов синхронизации у нас есть. Базисы — на то и базисы, что через них можно выразить всё.