Как мне синхронизировать (блокировать / разблокировать) доступ к файлу в bash из нескольких скриптов?
Я пишу сценарии, которые будут работать параллельно и будут получать свои входные данные из того же файла. Эти сценарии откроют входной файл, прочитают первую строку, сохранят его для дальнейшей обработки и, наконец, сотрут эту строку чтения из входного файла.
Теперь проблема заключается в том, что несколько сценариев, обращающихся к файлу, могут привести к ситуации, когда два сценария одновременно обращаются к входному файлу и читают одну и ту же строку, что приводит к недопустимому результату обработки строки дважды.
Теперь одно решение - написать файл блокировки (.lock_input
), прежде чем получить доступ к входному файлу, а затем стереть его при освобождении входного файла, но в моем случае это решение не подходит, поскольку иногда NFS произвольно замедляет сетевую связь и может не иметь надежной блокировки.
Другое решение состоит в том, чтобы установить блокировку процесса вместо записи файла, что означает, что первый скрипт для доступа к входному файлу запустит процесс с именем lock_input, а другие скриптыps -elf | grep lock_input
, Если он присутствует в списке процессов, они будут ждать. Это может быть быстрее, чем запись в NFS, но все же не идеальное решение ...
Итак, мой вопрос: Есть ли какая-либо команда bash (или другой интерпретатор сценариев) или служба, которую я могу использовать, которая будет вести себя как блокировки семафора или мьютекса, используемые для синхронизации в программировании потоков?
Спасибо.
Небольшой грубый пример:
Допустим, у нас есть input_file следующим образом:
Monday Tuesday Wednesday Thursday Friday Saturday Sunday
Сценарий лечения: TrScript.sh
#!/bin/bash
NbLines=$(cat input_file | wc -l)
while [ ! $NbLines = 0 ]
do
FirstLine=$(head -1 input_file)
echo "Hello World today is $FirstLine"
RemainingLines=$(expr $NbLines - 1 )
tail -n $RemainingLines input_file > tmp
mv tmp input_file
NbLines=$(cat input_file | wc -l)
done
Основной скрипт:
#! /bin/bash
./TrScript.sh &
./TrScript.sh &
./TrScript.sh &
wait
Результат должен быть:
Hello World today is Monday Hello World today is Tuesday Hello World today is Wednesday Hello World today is Thursday Hello World today is Friday Hello World today is Saturday Hello World today is Sunday