Как мне избежать этого состояния гонки с readdir / inotify? - PullRequest
2 голосов
/ 23 августа 2011

Предположим, я хочу вызвать какую-либо команду для всех файлов в каталоге и настроить наблюдение, чтобы вызывать эту команду для всех файлов, которые создаются в этом каталоге. Если я сделаю:

while( ( sdi = readdir( d )) != NULL ) { ... }
closedir( d );
/* Files created here will be missed */
inotify_add_watch( ... );

тогда некоторые файлы могут быть пропущены. Если я позвоню inotify_add_watch () перед readdir () файлы могут быть обработаны дважды (для этого потребуется Немного инфраструктуры, чтобы предотвратить действие дважды, и кажется, что крайние случаи будет трудно обрабатывать). Есть ли простой способ избежать необходимость записывать имена всех файлов, над которыми работали во время цикла readdir и сравнивать их с именами, возвращенными в структуре inotify_event? Я могу минимизировать количество необходимых сравнений с:

while( ( sdi = readdir( d )) != NULL ) { ... }
inotify_add_watch( ... );
while( ( sdi = readdir( d )) != NULL ) { /* record name */ ... }
closedir( d );

И обычно второй цикл readdir () ничего не делает, но это похоже на плохой взлом.

1 Ответ

1 голос
/ 23 августа 2011

Вы просто не можете.Чем больше вы взломаете, тем больше условий гонки вы получите.

Самое простое реально работающее решение - установить часы перед использованием opendir() и сохранить список (набор)уже использованные имена (или их хэши).

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

Лучший способ состоит в том, чтобы программа могла реально различать используемые файлы по их содержимому.Другими словами, вы устанавливаете watch, вызываете команду для результатов readdir(), затем вызываете ее для результатов inotify и сообщаете самой команде, в порядке ли файл уже или нет.

...