Inotify помещает в очередь события синхронно? - PullRequest
1 голос
/ 16 марта 2019

Я пытаюсь использовать inotify для мониторинга изменений файловой системы. В частности, я пытаюсь перехватить все обновления для файла в некотором предварительно настроенном каталоге.

Проблема возникла, когда я пытаюсь выключить приложение с помощью SIGTERM. Я хочу, чтобы все модификации были обработаны до этого.

ВОПРОС: Если единственный процесс, выполняющий изменение файла (write ing / mv ing), завершен, можно с уверенностью сказать, что если FIONREAD ioctl возвращает 0, тогда все модификации были извлечены из файлового дескриптора inotify. В документации указано:

FIONREAD ioctl(2) возвращает количество байтов, доступных для чтения. из дескриптора файла inotify.

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

Ответы [ 2 ]

3 голосов
/ 17 марта 2019

В этом вопросе и с принятым ответом происходит слияние нескольких вещей.

Чтобы ответить на суть вопроса:

Если единственный процесс, который изменяет файлы в просматриваемомместоположение прервано, после чего вы можете прекратить работу, если в очереди inotify больше нет событий.Вы можете безопасно проверить размер, проверив FIONREAD, как вы упомянули в вопросе.Чтобы это не пропустило ни одного события, вам необходимо точно знать, что процесс мутации определенно завершен с помощью других средств;критический аспект этого заключается в том, что вы не хотите завершать обработку очереди inotify, пока не завершится процесс мутации, и ваш процесс inotify получил SIGTERM.

Однако, если вы не знаете,другой процесс завершен, но вы хотите убедиться, что события до текущего момента времени (например, при обнаружении SIGTERM) были обработаны, вам нужно будет использовать метод, аналогичный тому, который использовался в watchman.Идея состоит в том, что вы создадите специальный файл маркера с волшебным именем в наблюдаемом каталоге, когда ваш основной процесс будет остановлен.Затем вы продолжите обрабатывать события из очереди inotify, пока не увидите свое волшебное имя файла;в этот момент вы можете сказать, что все события до создания магического файла были использованы.Здесь есть больше информации об этой технике: https://facebook.github.io/watchman/docs/cookies.html (отказ от ответственности: я создатель сторожа)

Дискуссия о signalfd против традиционной обработки сигналов ортогональна аспекту синхронизациивопрос: вы, конечно, можете использовать оригинальный интерфейс обработки сигналов posix и установить глобальную переменную, чтобы указать, что SIGTERM был получен.Это ничего не меняет в последовательности или времени событий inotify, поэтому не стесняйтесь использовать любой метод, который вам нравится при реализации этого.

3 голосов
/ 16 марта 2019

Я настоятельно рекомендую вам использовать signalfd, см. эту справочную страницу .

При этом сигналы доставляются по трубе, а действия по сигналу выполняются асинхронно. Таким образом, вы можете использовать реактор типа select() или epoll() для ожидания как в канале inotify, так и в файловом дескрипторе signalfd(), что позволит вам аккуратно управлять, когда вы на самом деле читаете сигнал с fd и обрабатываете его.

И, поскольку вы обрабатываете сигнал синхронно в основном цикле программы, а не в асинхронном сигнальном действии, нет никаких ограничений на то, какие функции вы можете вызывать при работе с сигналом.

По моему скромному мнению signalfd() намного, намного, намного превосходит старый и неприятный способ обработки сигналов. Единственный минус в том, что он (AFAIK) не переносим на другие * nixes.

...