Как я могу гарантировать, что одновременно выполняется только одна копия Perl-скрипта? - PullRequest
4 голосов
/ 19 октября 2010

Мне нужно убедиться, что одновременно запускается только одна копия моего Perl-скрипта. Согласно предложениям здесь я написал подпункт для проверки:

sub check_instances {
    open my $fh, '<', $0 or die $!; 

    unless (flock($fh, LOCK_EX|LOCK_NB)) {
        print "$0 is already running. Exiting.\n";
        exit 1;
    } 
}

Но это не работает. В чем может быть проблема?

Ответы [ 4 ]

5 голосов
/ 19 октября 2010

Вы используете лексический дескриптор файла, ограниченный внутри сабвуфера. Когда check_instances возвращается, файловый дескриптор автоматически закрывается, что снимает блокировку. Таким образом, вы никогда не увидите конфликта, если две копии не будут проверены одновременно.

Убедитесь, что файловый дескриптор остается открытым до тех пор, пока выполняется скрипт (или до тех пор, пока вы хотите сохранить блокировку). Например:

{
my $fh;
sub check_instances {
    return if $fh; # We already checked
    open $fh, '<', $0 or die $!; 

    unless (flock($fh, LOCK_EX|LOCK_NB)) {
        print "$0 is already running. Exiting.\n";
        exit 1;
    } 
}
} # end scope of $fh

Это также было бы хорошим местом для использования state переменной , если вам может потребоваться Perl 5.10.

2 голосов
/ 19 октября 2010

Обычная семантика flock может потребовать, чтобы вы открыли дескриптор файла в режиме записи, скажем,

open $fh, '>>', $0;
open $fh, '+<', $0;

perldoc -f flock)

Обратите внимание, что эмуляция fcntl (2) для flock (3) требует, чтобы FILEHANDLE был открыт с намерением чтения для использования LOCK_SH, и требует, чтобы он был открыт с намерением записи для использования LOCK_EX.

2 голосов
/ 19 октября 2010

Вы можете проверить список процессов для других экземпляров ( Proc :: ProcessTable может помочь), но общий путь, используемый программами unix на многих языках, заключается в создании файла pid - см. Файл :: Pid .

1 голос
/ 19 октября 2010

Блокировка файла может завершиться неудачей по разным причинам (например, если файл находится в сетевой файловой системе, такой как NFS).

Мое решение - создать каталог во время работы скрипта. Создание каталогов - это всегда атомарная операция.

...