Представьте себе два процесса, читателя и писателя, общающихся через обычный файл на ext3 fs. Читатель имеет IN_MODIFY
часы inotify на файл. Writer записывает 1000 байтов в файл за один write()
вызов. Читатель получает событие inotify и вызывает fstat
файл. Что видит Reader?
Есть ли гарантия, что Reader вернет по крайней мере 1000 фунтов за
st_size
файл? Из моих экспериментов, похоже, нет.Есть ли гарантия, что Reader может реально
read()
1000 байтов?
Это происходит в поле ввода / вывода с серьезными ограничениями. Например, sar
показывает время ожидания около 1 секунды. В моем случае Reader фактически ждет 10 секунд ПОСЛЕ получения события inotify перед вызовом stat
и получения слишком маленьких результатов.
Я надеялся, что событие inotify не будет доставлено, пока файл не будет готов. Я подозреваю, что на самом деле происходит то, что событие inotify запускается во время write()
вызова в Writer, и данные фактически становятся доступными для других процессов в системе, когда они оказываются готовыми. В этом случае 10 секунд не достаточно времени.
Я думаю, я просто ищу подтверждение того, что ядро фактически реализует inotify так, как я предполагаю. Кроме того, если есть какие-либо варианты, возможно, изменить это поведение?
Наконец, какой смысл inotify, учитывая это поведение? Вы все равно должны опрашивать файл / каталог после получения события, пока данные не станут фактически доступными. С таким же успехом можно делать это все время и забыть об inotify.
*** РЕДАКТИРОВАТЬ ** * * Хорошо, как часто бывает, поведение, которое я вижу, действительно имеет смысл, теперь, когда я понимаю, что я на самом деле делаю. ^ _ ^
На самом деле я отвечаю на событие IN_CREATE в каталоге, в котором находится файл. Поэтому я на самом деле stat () обрабатываю файл в ответ на создание файла, а не обязательно на событие IN_MODIFY, которое может появиться позже.
Я собираюсь изменить свой код так, чтобы после получения события IN_CREATE я подписывался на IN_MODIFY для самого файла и фактически не пытался прочитать файл, пока не получу событие IN_MODIFY. Я понимаю, что там есть небольшое окно, в котором я могу пропустить запись в файл, но это приемлемо для моего приложения, потому что в худшем случае файл будет закрыт через максимальное количество секунд.
Ответы:
Из того, что я вижу в исходном коде ядра , inotify запускается только после завершения записи (т. Е. Ваше предположение неверно). После того, как уведомление инициировано, происходит только две вещи
sys_write
, функция, которая реализуетwrite
системный вызов: установка некоторых параметров планировщика и обновление позиции в дескрипторе файла. Этот код был похож на 2.6.14 . Ко времени срабатывания уведомления файл уже имеет новый размер.Проверьте, что может пойти не так:
stat
а затем звонитread
или наоборот, что-то может произойти между ними. Если вы продолжаете добавлять к файлу, вызовstat
first гарантирует, что вы сможете прочитать это далеко, но возможно, что к моменту вызова читателя будет записано больше данныхread
, даже если он еще не получил уведомление inotify.write
факт, что программа записи вызывает , не означает, что ядро запишет запрошенное количество символов. Есть очень немного обстоятельств, когда атомарные записи гарантированы до любого размера. Однако каждыйwrite
вызов гарантированно атомарен: в какой-то момент данные еще не записаны, а затем внезапно записано n байтов, где n - возвращаемое значениеwrite
вызова. Если вы наблюдаете частично записанный файл, это значит, чтоwrite
возвращено меньше его аргумента размера.Полезные инструменты для расследования происходящего включают в себя:
strace -tt
источник