Как ограничить одновременные экземпляры одного и того же 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 вы также удалили этот файл.
Прочитайте соответствующие вопросы справа. Хотя они охватывают различные другие языки, предлагаемые ответы помогут понять проблемы и возможные способы обойти их на всех языках.