как сделать так, чтобы файл не читался до завершения записи в него

При попытке отслеживать каталог с помощью inotify в Linux, как мы знаем, мы получаем уведомление, как только файл создается (до того, как другой процесс закончит запись в него)

Есть ли эффективный способ убедиться, что файл не будет прочитан до того, как запись в него будет завершена другим процессом?

Потенциально мы могли бы добавить отложенное чтение; но, как мы все знаем, он ошибочен.

Для большей ясности в сценарии; два процесса выполняются от имени разных пользователей; ожидаемая нагрузка составляет около нескольких сотен файлов, создаваемых в секунду.


person ϹοδεMεδιϲ    schedule 16.07.2010    source источник
comment
Я полагаю, вы не можете просто создать именованный семафор для каждого файла, чтобы гарантировать, что только 1 процесс использует файл за раз?   -  person Gianni    schedule 16.07.2010
comment
Определить завершение... Если процесс не закрывает файл, возможно ли вообще определить, закончил ли процесс запись в него, хотя бы в принципе?   -  person Cogwheel    schedule 16.07.2010
comment
У вас есть контроль над программами, читающими/записывающими файл, или это также должно работать с любой сторонней программой?   -  person Jeremy Friesner    schedule 16.07.2010
comment
Вы имеете в виду синхронизацию процессов в основных терминах?   -  person Praveen S    schedule 16.07.2010
comment
Спасибо всем за быстрый ответ ... Процесс, который создает файл в отслеживаемом каталоге, является сторонним программным обеспечением, над которым я не имею никакого контроля. Тот, который отслеживает и читает файл; да, у меня есть полный контроль над этим.   -  person ϹοδεMεδιϲ    schedule 16.07.2010
comment
@Зубчатое колесо; под финишем я имел в виду, что файл создается процессом, записывает в него данные и закрывается.   -  person ϹοδεMεδιϲ    schedule 16.07.2010
comment
@ Новичок или наоборот? Похоже, что другой вопрос был задан после того, как этот был создан и ответил :)   -  person ϹοδεMεδιϲ    schedule 17.02.2015


Ответы (4)


Исходя из вашего вопроса, похоже, что вы в настоящее время отслеживаете каталог с флагом IN_CREATE (и, возможно, IN_OPEN). Почему бы также не использовать флаг IN_CLOSE, чтобы получать уведомления о закрытии файла? Оттуда должно быть легко отслеживать, открыл ли что-то файл, и вы будете знать, что пока не хотите пытаться его прочитать.

person jamessan    schedule 16.07.2010
comment
Спасибо, Джеймсан; ваш ответ помог мне найти решение, которое, кажется, работает для меня. Теперь я отслеживаю IN_CREATE и IN_CLOSE; объедините их, чтобы выбрать новые поступления в каталог, за которым я слежу! Спасибо за помощь. - person ϹοδεMεδιϲ; 19.07.2010

Создайте его в другом месте, напишите в него, закройте, а затем переименуйте — или я упустил что-то очевидное?

person Dipstick    schedule 16.07.2010
comment
Да, это правильный путь. Или создайте его под временным именем и переименуйте, когда закончите. - person MarkR; 17.07.2010
comment
Только если я контролирую процесс! Вот не хочу! Это сторонняя часть. - person ϹοδεMεδιϲ; 19.07.2010

Вы можете проверить /proc/<pid>/fd, чтобы убедиться, что файл все еще открыт. Если его там нет, вы можете быть уверены, что процесс его больше не использует.

person Gianni    schedule 16.07.2010
comment
есть ли способ узнать fd файла, открытого сторонним процессом; ни о ком я не слышал. Насколько я знаю, fd зависит от процесса, и только ОС и процесс будут знать о связи между fd и файлом на диске; если вообще есть способ, я почти уверен, что он будет доступен только для root. - person ϹοδεMεδιϲ; 16.07.2010
comment
@CodeMedic Посмотрите на директорию. fd является символической ссылкой на сам файл, поэтому вам не нужно преобразовывать fd -> имя, все, что вам нужно сделать, это использовать lstat, чтобы увидеть, на какой файл указывает ссылка. - person Gianni; 16.07.2010
comment
например: user@box:~# ls -l /proc/1433/fd/0 lr-x------ 1 root root 64 16.07.2010 15:31 /proc/1433/fd/0 -> /dev/ноль - person Gianni; 16.07.2010
comment
это будет работать только в том случае, если два процесса работают от одного и того же пользователя. Обычно /proc/‹PID›/fs/* доступны для чтения только пользователю. Вдобавок ко всему у нас будут проблемы с масштабируемостью из-за необходимости перебирать список каждую секунду или около того. В любом случае спасибо - person ϹοδεMεδιϲ; 16.07.2010
comment
@CodeMedic Ну, вы не указали это, поэтому я предлагаю вам отредактировать свой вопрос и добавить это. - person Gianni; 16.07.2010

возможно, команда lsof может помочь. В нем перечислены все открытые файлы. $ человек lsof

person Community    schedule 25.07.2010
comment
вопрос здесь не в том, чтобы сделать копию из оболочки. - person ϹοδεMεδιϲ; 27.07.2010