2014-12-11 6 views
2

У меня есть сценарий, который потенциально работает в течение длительного времени. В Linux. Пока он запущен, при повторном вызове тем же или другим пользователем он должен обнаружить это и отказаться от запуска. Я пытаюсь понять, как создать подходящий семафор, который очищается, даже если процесс по какой-то причине умирает.Как предотвратить запуск сценария Perl более одного раза параллельно

Я столкнулся с How to prevent PHP script running more than once?, который, конечно, можно применять, но мне интересно, можно ли это сделать лучше в Perl.

Например, у Perl есть флаг «очистка созданного временного файла при выходе процесса» (File :: Temp :: CLEANUP), который, как я считаю, вызывает триггеры, независимо от того, как завершился процесс. Но этот API можно использовать только для создания временных файлов с рандомизированными именами, поэтому он не будет работать как имя файла для семафора. Я не понимаю основной механизм того, как файл удаляется, но звучит как механизм существует. Как бы это сделать для имени файла, например./Вар/запустить/Foobar?

Или есть лучшие способы сделать это?

+0

Я сделал бы точно так же, как и с PHP: создать файл блокировки , – sebnukem

ответ

6
use strict; 
use warnings; 
use Fcntl ':flock'; 

flock(DATA, LOCK_EX|LOCK_NB) or die "There can be only one! [$0]"; 


# mandatory line, flocking depends on DATA file handle 
__DATA__ 
+0

Ты меня тут в тупик. Что это за бизнес __ DATA__? –

+2

@JohannesErnst check http://perldoc.perl.org/perldata.html#Special-Literals * Текст после __DATA__ может быть прочитан через дескриптор файла PACKNAME :: DATA, где PACKNAME - это пакет, который был текущим, когда был обнаружен токен __DATA__ , Дескриптор файла остается открытым, указывая на строку после __DATA __ * –

1

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

open(my $fh, '>', '/var/run/foobar'); 
print $fh "$$\n"; 
close $fh; 

Тогда вы можете прочитать его:

if (open(my $fh, '<', '/var/run/foobar')) { 
    while (my $PID = <$fh>) { 
     chomp $PID; 
     $proc = `ps hp $PID -o %c`; 
     if ($proc eq "foobar"){ 
      exit(); 
     } 
     break; 
    } 
} 

Вероятно, хотят сделать те, в другом порядке

Смежные вопросы