Я пишу сценарии, которые будут работать параллельно и получат их входные данные из того же файла. Эти сценарии откроют входной файл, считать первую строку, сохранить его для дальнейшего лечения и наконец стереть эту строку чтения из входного файла.
Теперь проблема состоит в том, что несколько сценариев, получающих доступ к файлу, могут привести к ситуации, где два сценария получают доступ к входному файлу одновременно и читают ту же строку, которая приводит к недопустимому результату строки, обрабатываемой дважды.
Теперь одно решение состоит в том, чтобы записать файл блокировки (.lock_input
) прежде, чем получить доступ к входному файлу, и затем стирают его при выпуске входного файла, но это решение не обращается в моем случае, потому что иногда NFS замедляет сетевую связь случайным образом и не может иметь надежной блокировки.
Другое решение состоит в том, чтобы поместить блокировку процесса вместо того, чтобы писать файл, что означает, что первый сценарий, который получит доступ к входному файлу, запустит процесс, названный lock_input, и другие сценарии будут ps -elf | grep lock_input
. Если это будет присутствовать на списке процессов, то они будут ожидать. Это может быть быстрее, чем запись в NFS, но все еще идеальное решение...
Таким образом, мой вопрос: Есть ли какая-либо команда удара (или другой интерпретатор сценария) или сервис, который я могу использовать, который будет вести себя как семафор или взаимоисключающие блокировки, используемые для синхронизации в программировании потока?
Спасибо.
Небольшой грубый пример:
Скажем, у нас есть 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
Мне всегда нравилась программа lockfile (пример результатов поиска для lockfile man-страницы ) из procmail набор инструментов (должен быть доступен в большинстве систем, хотя может не быть установлен по умолчанию).
Он был разработан для блокировки файлов спула почты, которые (были?) Обычно монтируются через NFS, поэтому он правильно работает через NFS (насколько это возможно).
Кроме того, если вы предполагаете, что все ваши «рабочие» находятся на одном компьютере (предполагая, что вы можете проверять PID, которые могут работать некорректно, когда PID в конечном итоге переносятся), вы можете установить блокировку файл в другом локальном каталоге (например, / tmp) при обработке файлов, размещенных на сервере NFS. Пока все рабочие процессы используют одно и то же расположение файла блокировки (и взаимно однозначное сопоставление имен файлов файлов блокировки с заблокированными путями), он будет работать нормально.
используйте
line=`flock $lockfile -c "(gawk 'NR==1' < $infile ; gawk 'NR>1' < $infile > $infile.tmp ; mv $infile.tmp $infile)"`
для доступа к файлу, из которого вы хотите читать. Однако при этом используются блокировки файлов.
gawk NR==1 < ...
печатает первую строку ввода