Это проблема столовых философов . Сортируя блокировки, вы реализуете решение по иерархии ресурсов .
Хотя решение по иерархии ресурсов позволяет избежать взаимоблокировок, оно не всегда практично, особенно когда список необходимых ресурсов заранее не известен полностью.
Похоже, что это надежно, если только вы можете сортировать свои ресурсы и придерживаться его.
Обходной путь может заключаться в том, чтобы не flock
ждать неопределенно долго, а затем добавить некоторую логику для обнаружения случаев, когда он вышел из-за невозможности заблокировать файл и, например, повторить всю задачу через некоторое случайное время.
В man flock
одном можно увидеть:
-n
,--nb
,--nonblock
Нормально (с выходными кодом1
), а не ждать, если блокировка не может быть немедленно приобретена.
-w
,--wait
,--timeout seconds
Нормально (с выходными кодом1
), если блокировка не может быть приобретена в течение нескольких секунд секунд. Десятичные дробные значения допускаются.
Проблема в том, что возможный код выхода 1
может исходить от любой flock
или от базовой команды. Если вы flock
поддерживаете -E
указание пользовательского кода выхода - используйте его, возможно.
Это простой пример подхода:
while ! flock -n -x file <command> ; do sleep $(($RANDOM%5)) ; done
Вы можете использовать несколько flock
-s. Если какой-либо из них не может заблокировать файл, все блокировки снимаются, и вся строка ожидает в sleep
, а не в flock
; в это время он не будет блокировать другую аналогичную линию, выполняемую параллельно.