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

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

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

Теперь одно решение состоит в том, чтобы записать файл блокировки (.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
19
задан sth 24 February 2010 в 01:59
поделиться

2 ответа

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

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

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

10
ответ дан 30 November 2019 в 04:24
поделиться

используйте

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

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

gawk NR==1 < ...

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

15
ответ дан 30 November 2019 в 04:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: