Подтвердить что ты не робот

Как синхронизировать (блокировать/разблокировать) доступ к файлу в bash из нескольких сценариев?

Я пишу скрипты, которые будут запускаться параллельно, и получат их входные данные из того же файла. Эти сценарии откроют входной файл, прочитайте первую строку, сохраните его для дальнейшего лечения и, наконец, удалите эту строку чтения из входного файла.

Теперь проблема в том, что несколько сценариев, обращающихся к файлу, могут привести к ситуации, когда два сценария одновременно получают доступ к входному файлу и считывают одну и ту же строку, что приводит к недопустимому результату обработки строки дважды.

Теперь одно решение - записать файл блокировки (.lock_input) перед доступом к входному файлу, а затем стереть его при выпуске входного файла, но это решение не привлекательно в моем случае, потому что иногда NFS замедляет сетевую связь в случайном порядке и может не иметь надежной блокировки.

Другим решением является установка блокировки процесса вместо записи файла, что означает, что первый script для доступа к входному файлу запустит процесс с именем lock_input, а остальные скрипты будут ps -elf | grep lock_input. Если он присутствует в списке процессов, они будут ждать. Это может быть быстрее, чем запись в NFS, но все еще не идеальное решение...

Итак, мой вопрос: есть ли какая-либо команда bash (или другой интерпретатор script) или служба, которую я могу использовать, которая будет вести себя как блокировки семафора или мьютекса, используемые для синхронизации в программировании потоков

Спасибо.

Небольшой пример:

Скажем, у нас есть input_file, как показано ниже:

Monday
Tuesday
Wednesday
Thursday
Friday
Saturday 
Sunday

Лечение script: 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

Основной script:

#! /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
4b9b3361

Ответ 1

Мне всегда нравилась программа lockfile (образец результата поиска для файл блокировки файла) из набора инструментов procmail (должен быть доступен в большинстве систем, хотя он не может быть установлен по умолчанию).

Он был предназначен для блокировки почтовых файлов спула, которые (были?) обычно монтируются через NFS, поэтому он корректно работает над NFS (насколько это возможно).

Кроме того, до тех пор, пока вы делаете предположение, что все ваши "рабочие" находятся на одной машине (предполагая, что вы можете проверить PID, что может не работать должным образом, когда PID в конечном итоге завершают), вы можете поместить свой файл блокировки в каком-либо другом локальном каталоге (например,/tmp) при обработке файлов, размещенных на сервере NFS. До тех пор, пока все рабочие используют одно и то же расположение файла блокировки (и сопоставление "один-к-одному" имен файлов блокировки с заблокированными именами путей), он будет работать нормально.

Ответ 2

использование

line=`flock $lockfile -c "(gawk 'NR==1' < $infile ; gawk 'NR>1' < $infile > $infile.tmp ; mv $infile.tmp $infile)"`

для доступа к файлу, который вы хотите прочитать. Это использует блокировки файлов.

gawk NR==1 < ...

выводит первую строку ввода

Ответ 3

Используя инструмент FLOM (Free LOck Manager), ваш основной script может стать таким же простым, как:

#!/bin/bash  
flom -- ./TrScript.sh &  
flom -- ./TrScript.sh &  
flom -- ./TrScript.sh &  
wait

если вы используете script внутри одного хоста и что-то вроде:

flom -A 224.0.0.1 -- ./TrScript.sh &

если вы хотите распространять свой script на многих хостах. Некоторые примеры использования доступны по этому URL-адресу: http://sourceforge.net/p/flom/wiki/FLOM%20by%20examples/