Как ограничить одновременные экземпляры одного и того же Ruby script?

В Ruby 1.9.x, что может быть простым способом либо не разрешить запуск Ruby script, либо дождаться завершения предыдущего экземпляра? **

Я надеюсь избежать беспорядочной блокировки файлов или проверки таблицы процессов.

Есть ли что-то вроде глобальных мьютексов или семафор уже в ядре? Я изучил родной Mutex, но это, похоже, применимо только к потокам в рамках одного процесса Ruby, а не к различным процессам.

** Позже я мог бы добавить функции тайм-аута или ограничить N экземпляров, или попытаться использовать более одной глобальной блокировки (по одному на общесистемный ресурс, который должен иметь только один экземпляр).

Ответ 1

Этот очень короткий код замерзнет, ​​пока не будет заблокирован файл блокировки в /tmp, названный после того, как ваш script заблокирован:

File.open("/tmp/#{File.basename $0}.lock", File::RDWR|File::CREAT, 0644).flock(File::LOCK_EX)

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

timeout 1m ./myrubyscript.rb

из упаковки bash script, если я буду нетерпеливым, например. (В этом примере myrubyscript.rb закончит через 1 минуту, будет ли он или нет, и его файловая блокировка продолжит выполнение того, что было написано.)

Ответ 2

Обычно это решается на уровне ОС, проверяя флаг файл и не запуская его снова, а не только в script.

Но, если вы хотите проверить script, найдите файл семафора в известном месте. Если он существует, и он не находится в заданном временном окне, которое находится в вашем окне запуска, затем удалите файл и создайте новый. Если это в вашем окне времени, то выйдите.

Вы можете использовать блокировку файлов или хранить метки времени в файле или многие другие проверки, если вы не запускаете механизм cron-типа. Каждый подход имеет свои плюсы и минусы.

Вы хотите захватить прерывания, чтобы при выходе из Control-C вы также удалили этот файл.

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