У меня есть несколько команд, которые я хотел бы выполнять параллельно, но только если нет конфликтов в ресурсах, к которым они получают доступ. Поэтому я решил использовать flock
. Каждая команда должна иметь одну исключительную (запись) блокировку и несколько общих (чтение) блокировок. Поскольку flock
не поддерживает множественные блокировки, я наивно думал, что-то вроде:
flock -x a flock -s b flock -s c ... <command>
должно сработать. Я быстро обнаружил, что при таком подходе существуют условия гонки, поскольку набор блокировок не является атомарным. При запуске:
flock -x a flock -s b <command1> &
flock -x b flock -s a <command2> &
может случиться так, что две эксклюзивные блокировки будут приняты одновременно, и две команды войдут в тупик, потому что они не могут взять свои общие блокировки.
Есть ли обходной путь? Являются ли они другими утилитами блокировки, которые поддерживают множественные блокировки атомарным способом? Или я должен создать свой собственный, который пытается захватить блокировки, отпустить их все по истечении времени ожидания, если он выходит из строя, и повторить попытку после случайной задержки? Или что-то подобное?
Обновление видимо, сортировка блокировок по имени решает проблему:
flock -x a flock -s b <command1> &
flock -s a flock -x b <command2> &
но насколько это надежно? Будет ли он избегать взаимоблокировок во всех ситуациях с любым количеством команд, количеством блокировок, имен блокировок и наборов блокировок на команду (все еще с ограничением, что для каждой команды существует только одна исключительная блокировка)?