понедельник, 10 октября 2011 г.

Solaris 11: File Event Notification

Сделал демона, который файлы и папки проверяет на наличие изменений. Если изменения происходят, то запускается скрипт, описанный в файле конфигурации.

Подробности реализации:


Запускать процессы (скрипты) можно в одном варианте fork() + exec().
этот вариант не нравится потому, что выглядит сумрачно. На каждый запуск скрипта операционная система вынуждена копировать сегменты данных, которые в общем случае занимают мегабайты.
Реализация может быть выполнена с использованием модификации vfork() которая запускает новый процесс на том же сегменте данных.

В Solaris функцию vfork() использовать не рекомендуется, предлагают использовать posix_spawn(). А как насчет GNU/Linux?

Интересное замечание относительно использования функции system(), которая кажется более простым способом запуска скриптов. А все не так, в POSIX сказано, что она обязана вызвать функцию fork и exec. Кроме того функция блокирующая, а меня интересует неблокирующий запуск скриптов.

Неблокирующий запуск процессов в моем случае должен еще следить, чтобы на посторное изменение папки скрипт параллельно не запускался, чтобы не зависал.


Другая проблема, с которой столкнулся, хотел чтобы в процессе проверки мне возвращался статус завершения процесса. А процесс завершается себе и не осталяет информации о статусе. Для этого можно использовать функцию forkx() или vforkx() с параметром FORK_WAITPID. В таком варианте дочерний процесс после завершения "зомбируется" и ждет пока его спросят о статусе завершения.

Моя программа считывает из файла конфигурации список файлов/папок и соответствующих скриптов. Каждую секунду производится опрос состояния папок по списку с использованием неблокирующего вызова waitpid().

Тут хочется вызвать что-нибудь такое чтобы настроить закладки по списку и не проверять вовсе. Чтобы система вызывала мою программу всякий раз, когда произощло хоть какое-нибудь событие с файлом. Порылся в документации нашел File Events Notification (FEN) API представленное в Solaris функциями port_associate, port_get ... Опять проблема с совместимостью с GNU/Linux и код в результате, судя по примерам, не кажется таким уж компактным. Может как-нибудь и попробую использовать это API но пока что забраковал.

Разработка такой программы заняло 1 день с использованием glib, потом еще один день чтобы написать это более оптимально и еще два дня чтобы избавится от glib и прочих библиотечных наростов. Переписал парсер командной строки и валидатор UTF-8, работу со списками, менеджер динамической памяти, управление журналом, разбор параметров командной строки и прочие мелочи. Не люблю когда простая и компактная программа тянет за собой здоровые библиотеки. Люблю позаниматься оптимизацией кода, хоть в этом и не видно смысла.

Комментариев нет:

Отправить комментарий