Почему стадо bash с выходом по тайм-ауту не может получить блокировку? - PullRequest
2 голосов
/ 24 мая 2010

Я играю с использованием flock, команды bash для блокировки файлов, чтобы два и более экземпляра кода не запускались более одного раза.

Я использую этот код тестирования:

( ( flock -x 200 ;  sleep 10 ; echo "original finished" ; ) 200>./test.lock ) &
( sleep 2 ; ( flock -x -w 2 200 ; echo "a finished" ) 200>./test.lock ) &

У меня работает 2 подшкура (фон). Синтаксис (flock NUM; ...) NUM>FILE взят из справочной страницы flock .

Я ожидаю, что первая подоболочка получит эксклюзивную блокировку на test.lock, затем подождет 10 секунд, затем напечатает «оригинал закончен», все время удерживая блокировку. Второй подоболочек начнется примерно в то же время, подождите 2 секунды, затем попытайтесь получить блокировку test.lock, но через 2 секунды произойдет тайм-аут. Если он получит блокировку, то он напечатает «готово». Если он не получит блокировку, то подоболочка должна прекратиться, и ничего не должно быть напечатано.

Поскольку первый подоболочек ожидает дольше, он будет удерживать блокировку в течение 10 секунд, поэтому второй подоболочек не должен получить блокировку и не должен завершаться. то есть вы должны увидеть «оригинал закончен» напечатанным и , а не оба.

На самом деле происходит то, что печатается «готово», а затем печатается «готово».

Это означает, что второй подоболочек либо (а) не использует ту же блокировку, что и первый подоболочек, либо (б) он не может получить блокировку, но продолжает выполняться, либо (в) что-то еще.

Почему эти замки не работают так, как я ожидаю?

1 Ответ

5 голосов
/ 24 мая 2010

Проблема в том, что если процессу flock не удается получить блокировку в течение тайм-аута, он не может уничтожить родительский процесс (т. Е. Оболочку, которая его породила) - все, что он может сделать, это вернуть возврат ошибкикод.Вы должны проверить этот код возврата, прежде чем продолжить:

flock <params> && <do other stuff>

так что

( ( flock -x 200 ;  sleep 10 ; echo "original finished" ; ) 200>./test.lock ) & ( sleep 2 ; ( flock -x -w 2 200 && echo "a finished" ) 200>./test.lock ) &

делает то, что вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...