Pull to refresh

Comments 71

man 1 flock
функций даже побольше, есть в стандартных конфигурациях в линуксе
Прекрасно, а дальше что? Самому еще раз написать эту утилиту? Она как раз флок и использует.
flock(1) это и есть утилита.
// Сохранение в $lock_file обязательно, иначе handle помрёт и файл автоматом закроется
if(!flock($lock_file = fopen("my_script.lock", 'w'), LOCK_EX | LOCK_NB))
  die("Already runninng\n");
А вот за это спасибо: замены для lockrun меня лично не особо интересуют, а для скриптов идея хороша. Возьму на заметку.
Огромное спасибо! Очень помогло!
Ого, а я как дурак для этого скрипт на шелле использовал, вот такой: code.reddit.com/browser/scripts/saferun.sh

Я туда правда добавил еще проверку load average, чтобы некоторые скрипты могли подождать если в момент, когда крон их решил запустить уже и так нагрузка высокая. Но проверку на существование процесса надо будет на flock переделать на досуге.
Нашел на линуксовом сервере. На freebsd найти не удалось, оно там есть?
на сколько я знаю, нету.
для BSD пойдёт :)
Я тут над flock экспериментирую — никак не могу заставить его ругаться при выходе. Это возможно?
Он выставляет статус, можно на него ругаться вручную через $?
То есть ему еще обертку писать?
Зависит от ситуации.
Часто бывает проще написать
$ flock -n /tmp/lock -c mycommand || echo Fail
чем что-то качать, собирать и ставить.
Ну в общем да. Правда, у меня-таки фря на сервере.
Если обертку, то получится, что flock больше все-таки для встраивания в шелл-скрипты, а lockrun для самостоятельного использования. Я прав?
Так можно сказать, но обычно приходится использовать то, что уже стоит на сервере.
Качают и ставят — когда совсем нечем заменить. или нечем заняться 8)
Отвыкли в наше время качать и ставить-то! %)
UFO just landed and posted this here
О. А пример использования в описанном контексте не подкинете?
* * * * * /usr/local/bin/lockrun --lockfile=/tmp/megacache.lockrun — /path/to/megacache/generator

* * * * * lockf /tmp/megacache.lockrun /path/to/megacache/generator
[mixailo@DTG1127 ~]$ lockf pid.lock sleep 60 &
[1] 69177
[mixailo@DTG1127 ~]$ lockf pid.lock sleep 60 &
[2] 69352

Не то что-то.
Почитайте man. Там написано, что по умолчанию, lockf будет бесконечно ждать освобождения лок-файла.

У вас в примере вторая команда ждёт выполнения первой для начала своей работы.
А если поставит нулевое время ожидания:

[root@bsd ~]# lockf -t 0 pid.lock sleep 60 &
[1] 65999
[root@bsd ~]# lockf -t 0 pid.lock sleep 60
lockf: pid.lock: already locked
Вроде же в линуксе есть нормальные именованые мютексы, которые могут использоваться для этой задачи куда удобнее и эффективнее, чем файлы. Я бы понял, если бы решение было на PHP, но вы используете С (кстати, программы на С не зовутся скриптами) — почему не мютексы?
Я не автор скрипта, поэтому не могу ответить вам на этот вопрос.
Ну, файлы — это Unix way. Это даёт возможность для просмотра установленных блокировок использовать ls (dir в windows).
В этом что-то есть, хотя родной линуксовый flock за собой файл не удаляет.
Я еще не слышал, чтобы Unix way-ем называли использованием неподходящих инструментов при наличии подходящих.
А чем он неподходящий? Кроме того, что мьютекс, условно говоря, находится в пространстве имён недоступном через файловый API.
В Win32 мютекс от приложения, которое умерло не своей смертью, умирает вместе с ним (точнее, переходит в состояние abadonned) и в результате становятся не нужны экзорцизмы, связанные с удалением файла в случае некорректного завершения работы.
>не нужны экзорцизмы, связанные с удалением файла в случае некорректного завершения работы.

они и в юниксах не нужны
Это да. Но если есть (я не смотрел) простой способ определить открыт ли кем-то файл, то это решает проблему.
Мне концепция Plan 9 покоя не даёт :)
Есть, для этого нужно всего лишь открыть файл эксклюзивно (FILE_SHARE_NONE, или аналоги). Только экзорцизмы с файлами мне все равно непонятны. Файл должен служить для того, для чего предназначен.
UFO just landed and posted this here
У меня по дефолту такое:
mixailo@db:~$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
mixailo@db:~$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=10.04
DISTRIB_CODENAME=lucid
DISTRIB_DESCRIPTION="Ubuntu 10.04.1 LTS"
UFO just landed and posted this here
Это не так важно, важно что бы при запущеной программе лок на файл был экслюзивный.
Менее надёжно, но более популярно:

ln -s $$ lock-file || exit
trap "rm -f lock-file" EXIT
trap "trap - EXIT; rm -f lock-file" HUP INT QUIT


Если произошёл коллапс и файл-таки остался, то вместо "|| exit" можно осуществлять проверку существования процесса.
Плюс в том, что если cleanup не отработал, то произошло что-то плохое и это дело лучше разгрести руками.
Вау. А что делает последняя строчка?
Трап на попытку прибить скрипт ставит трап на EXIT и если получает exit то… вот дальше непонял.
Ай, бага ручного ввода, надо было копипастить :( в последней строчке должен быть exit в самом конце обработчика.

Обработчик (на стандартные сигналы завершения, можно при желании пополнить список) сбрасывает хук на выход, освобождает файл и выходит (в этот момент хук на выход уже сброшен, так что файл 2й раз не удаляется).
apt-cache show lockfile-progs

cron, между прочим, recommends.

Пример использования в /etc/cron.daily/standard
Спасибо за поднятую тему. Узнал про flock!
Я тоже %) Только мне бестолку — у меня фряха на сервере.
Port: flock-3.4_1
Path: /usr/ports/sysutils/flock
Info: Assert/wait for advisory locks with flock(2)
Maint: ports@FreeBSD.org
B-deps: mkcmd-8.14 msrc0-0.7
Упоминалось еще вчера (пруф).
Хотя я, в общем-то, и не претендовал на то, что описанное решение самое лучшее или единственное.
я видел. Просто не заметил, что там тоже были вы :)
Собственно, ничего страшного. Про хорошую вещь можно и повторить
Я тут немного отрекламирую «замену крона»: http://search.cpan.org/~kohts/snaked-0.07/lib/snaked.pm
Кому-то может показаться, что это «изобретание велосипеда», но на самом деле — штука очень удобная и умеет справляться с описанной в топике задачей.
UFO just landed and posted this here
pidof -s -o '%PPID' -x $( basename $0 ) > /dev/null 2>&1 && exit
А что не так с классическим
*/5 * * * * pgrep -f my_command &>/dev/null || my_command
применительно к конкретной ситуации описанной в начале?
Строго говоря, race condition'ом — два pgrep'а проверяют, что команда не запущена, и оба синхронно весело запускают два экземпляра.
А чем плох mktemp? Проверяем не создан ли временный файл, если нет, создаем и запускаем скрипт. Файл прибивается автоматически при завершении скрипта.
Ничем, скорее всего, не плохо любое решение, к которому вы привыкли.
Я вот к lockrun привык.
>Чем плох?
дополнительными не дающими 100% гарантии костылями для обработки аварийного завершения скрипта?
По моему вполне хватает создания файла и его удаления после выполнения скрипта, так в большинстве скриптов реализовано в линуксе.
Выше уже писали, что внезапная смерть скрипта создает проблемы в виде неудаленного файла. Можно проверять пид на существование, но это не дает 100% гарантии.
Ну добавьте ещё проверку ps ax|grep имя скрипта на такой случай.
Во-во, пошли костыли.
Где вы увидели костыли? Это простые и надежные юниксвей методы.
Не хватает тега «сарказм».
Есть еще lckdo — включен в стандартный дебиановский репозиторий.
Sign up to leave a comment.

Articles