Как я могу убедиться, что только одна копия сценария Perl работает одновременно?

StackOverflow https://stackoverflow.com/questions/3966472

  •  09-10-2019
  •  | 
  •  

Вопрос

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

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;
    } 
}

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

Это было полезно?

Решение

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

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

{
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.

Другие советы

Вы можете проверить список процессов для других экземпляров (Proc :: plachtable. Может помочь), но обычный маршрут, принятый программами Unix на многих языках - создать файл PID - см. Файл :: PID.

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

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

(От perldoc -f flock)

Обратите внимание, что эмуляция FCNTL (2), эмуляция стада (3) требует, чтобы Filehandle быть открытым с помощью прочитанного намерения использовать lock_sh и требует, чтобы он был открыт с намерением для записи для использования lock_ex.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top