Какой хороший портативный способ реализации глобального сигнального события в среде POSIX
Вопрос
Случай использования заключается в том, что одно приложение генерирует событие и отправляет сигнал, который получает любое приложение, которое заботится о нем. Например, приложение обновляет содержимое файла и сигнализирует об этом. На Linux это может быть сделано официантами, вызывшими INOTIFY в файле. Одним из портативных способов будет прослушивание, чтобы зарегистрироваться на известном сервере, но я бы предпочел что-то проще, если это возможно. Как можно более портативно, в идеале означает использование только функций Posix, которые также широко доступны.
Решение
Опция с использованием файлов блокировки
Вы можете сделать это, заблокировав файл.
Начальная установка излучения сигнала:
- Создайте файл с известным именем и заблокируйте его для написания (
fcntl(F_SETLK)
сF_WRLCK
или стая (lock_ex) `).
Процедура приемника сигнала:
- Откройте файл, используя известное имя файла и попробуйте получить блокировку чтения (
fcntl(F_SETLK)
сF_RDLCK
илиflock(LOCK_SH)
). - Приемные блоки, потому что излучатель держит противоречивую блокировку записи.
Эмиссия сигнала:
- Излучатель сигнала создает новый временный файл
- Излучатель сигнала получает блокировку записи в новом временном файле
- Излучение сигнала переименовывает новый временный файл в известное имя файла. Это Clobbers старый файл блокировки, но ожидающие приемники сохраняют на него ссылки.
- Излучение сигнала закрывает старый файл блокировки. Это также выпускает замок.
- Приемники сигнала просыпаются, потому что теперь они могут получить свои блокировки чтения.
- Приемники сигналов должны закрыть только что, на котором они только что получили блокировку. Это не будет использовано снова. Если они хотят ждать, пока условие произойдет снова, они должны открыть файл.
В эмиттере сигнала временным файлом блокировки, который был переименован в верхней части исходного файла блокировки, теперь становится новым текущим файлом блокировки.
Вариант с использованием сетевой многоадресной рассылки
Попросите приемников присоединиться к многоадресной группе и ждать пакетов. Пусть сигнал излучатель отправляет пакеты UDP в эту многоадресную группу.
Вы можете связать как отправку, так и получение гнезда UDP с интерфейсом Loopback, если вы хотите, чтобы она использовала только локальную связь.
Другие советы
В конце я использовал связанный домен Unix Domain. Владелец сохраняет множество клиентских FDS и отправляет каждому сообщение, когда есть событие.