Wie kann ich nur eine Kopie eines Perl-Skript gewährleisten zu einem Zeitpunkt ausgeführt wird?

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

  •  09-10-2019
  •  | 
  •  

Frage

Ich brauche, dass nur eine Kopie meines Perl-Skript, um sicherzustellen, wird zu einem Zeitpunkt ausgeführt wird. Nach den Vorschlägen hier ich eine Unter schrieb den Scheck zu tun:

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

Aber es funktioniert nicht. Was kann das Problem sein?

War es hilfreich?

Lösung

Sie verwenden eine lexikalische Dateikennung innerhalb des Unter scoped. Wenn check_instances zurückkehrt, wird die Dateikennung automatisch geschlossen, der die Sperre. So werden Sie nie einen Konflikt, wenn nicht zwei Kopien prüfen genau zur gleichen Zeit sehen.

Stellen Sie sicher, dass die Dateikennung bleibt so lange geöffnet, wie das Skript ausgeführt wird (oder so lange, wie Sie die Sperre aufrechterhalten wollen). Zum Beispiel:

{
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

Dies wäre auch ein guter Ort, um eine state Variable , wenn Sie können benötigen Perl 5.10.

Andere Tipps

Sie können für andere Instanzen die Prozessliste überprüfen ( Proc :: ProcessTable kann helfen,), aber eine gemeinsame Route von Unix-Programmen in vielen Sprachen genommen ist eine pid-Datei zu erstellen - siehe File :: Pid .

Die normale Semantik von flock können benötigen Sie die Dateikennung im Schreibmodus zu öffnen, sagen wir,

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

(von perldoc -f flock )

Beachten Sie, dass die fcntl (2) Emulation der Herde (3) verlangt, dass FILEHANDLE offen mit Absicht lesen LOCK_SH zu bedienen und erfordert dass es mit Schreib offen Absicht LOCK_EX zu verwenden.

File locking can fail for various reasons (for example if the file is on a network file system like NFS).

My solution is to create a directory while the script runs. Creating directories is always an atomic operation.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top