Comment puis-je assurer qu'une seule copie d'un script Perl est en cours d'exécution à la fois?

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

  •  09-10-2019
  •  | 
  •  

Question

Je dois faire en sorte que seule une copie de mon script Perl est en cours d'exécution à la fois. Selon les suggestions j'ai écrit un sous pour faire le contrôle:

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

Mais cela ne fonctionne pas. Que peut-être la question?

Était-ce utile?

La solution

Vous utilisez un lexique descripteur de fichier scope à l'intérieur du sous. Au retour check_instances, le descripteur de fichier est fermé automatiquement, ce qui libère le verrou. Donc, vous ne verrez jamais un conflit à moins que deux copies vérifier exactement en même temps.

Assurez-vous que les restes handles de fichiers ouverts aussi longtemps que le script est exécuté (ou aussi longtemps que vous voulez maintenir le verrou). Par exemple:

{
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

Ce serait également un bon endroit pour utiliser une variable state , si vous le pouvez exigent Perl 5.10.

Autres conseils

Vous pouvez consulter la liste des processus pour d'autres instances ( Proc :: ProcessTable peut aider), mais une voie commune prise par les programmes unix dans de nombreuses langues est de créer un fichier pid - voir fichier :: Pid.

La sémantique normale de flock peut vous obliger à ouvrir le descripteur de fichier en mode écriture, disons,

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

(De perldoc -f flock )

  

Notez que le fcntl (2) l'émulation du troupeau (3) exige que      FILEHANDLE être ouvert en lecture intention d'utiliser LOCK_SH et exige      que ce soit ouvert avec écriture intention d'utiliser LOCK_EX.

Le verrouillage des fichiers peut échouer pour diverses raisons (par exemple si le fichier est sur un système de fichiers réseau comme NFS).

Ma solution est de créer un répertoire alors que le script est exécuté. Création de répertoires est toujours une opération atomique.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top