Авторами книги является Kernigan и Pike, заголовок - что-то как "Среда программирования Unix".
Книгу, из которой я на самом деле извлек уроки, назвали "Введением в Unix Berkely".
Если lockfile
не установлен в Вашей системе, затем mkdir
сделает работу: это - атомарная операция, и это перестало работать, если каталог уже существует (как долго, поскольку Вы не добавляете -p
переключатель командной строки).
create_lock_or_wait () {
path="$1"
wait_time="${2:-10}"
while true; do
if mkdir "${path}.lock.d"; then
break;
fi
sleep $wait_time
done
}
remove_lock () {
path="$1"
rmdir "${path}.lock.d"
}
#!/bin/bash
# Makes sure we exit if flock fails.
set -e
(
# Wait for lock on /var/lock/.myscript.exclusivelock (fd 200) for 10 seconds
flock -x -w 10 200
# Do stuff
) 200>/var/lock/.myscript.exclusivelock
Это гарантирует, что код между" (" и")" выполняется только одним процессом за один раз и что процесс действительно ожидает блокировки слишком долго.
lockf(1)
не работает в пути, используемом в этом примере, все же. Это не может взять число дескриптора файла в качестве аргумента.
– Charley
28.10.2016, 10:36
lockfile (1) похож на хорошего кандидата, хотя остерегаются этого, это - часть procmail пакета, который Вы еще не могли установить на своей машине. Это - достаточно популярный пакет, что это должно быть упаковано для Вашей системы, если это еще не установлено. Три из этих четырех систем, которые я проверил, имеют его, и другой имеет его в наличии.
Используя его просто:
#!/bin/sh
LOCKFILE=$HOME/.myscript/lock
mkdir -p `dirname $LOCKFILE`
echo Waiting for lock $LOCKFILE...
if lockfile -1 -r15 $LOCKFILE
then
# Do protected stuff here
echo Doing protected stuff...
# Then, afterward, clean up so another instance of this script can run
rm -f $LOCKFILE
else
echo "Failed to acquire lock! lockfile(1) returned $?"
exit 1
fi
Опции, которые я дал, заставляют его повторить однажды секунда в течение максимум 15 секунд. Отбросьте флаг "-r", если Вы хотите, чтобы он ожидал навсегда.
Системный вызов mkdir()
является атомарным в файловых системах POSIX. Так, использование mkdir
команда таким способом, к которому это включает точно один вызов mkdir()
достиг бы Вашей цели. (IOW, не использовать mkdir -p
). Соответствие разблокировало, rmdir
конечно.
Принцип "качество на риск покупателя": mkdir()
не могло бы быть атомарным в сетевых файловых системах.
Возможно, команда lockfile сделает то, в чем Вы нуждаетесь.
lockfile ~/.config/mylockfile.lock
.....
rm -f important.lock
FLOM позволяет реализовать более софистичные случаи использования (распределенная блокировка, читатели/писатели, числовые ресурсы и т.д......................... как здесь объяснено: [112560]http://sourceforge.net/p/flom/wiki/FLOM%20by%20examples/
Если вы работаете только на Unix, используйте fifos. Вы можете записывать рабочие записи в fifo и читать процессы из этого файла, а ваши читатели будут блокироваться в fifos.
Блокировать файлы нормально, но для того, что вы описываете, я бы использовал fifos
.