2012-02-22 8 views
6

Sto scrivendo uno script Perl (ad esempio script.pl) che chiama un altro script newscript.pl. Voglio ottenere i PID di entrambi gli script solo in script.pl. Posso ottenere il PID di script.pl utilizzando il codice seguenteCome si ottiene il PID di un processo generato con la funzione di sistema di Perl?

my $pid = Unix::PID->new(); 
my @p = $pid->get_pidof($pid->get_command($$), 1); 

Dopo questo io chiamo system eseguire newscript.pl

system("perl newscript.pl"); 

voglio catturare il PID generato da questo newscript.pl in script.pl.

risposta

5

Per il momento system restituisce, il processo generato sarà già terminato, lasciando il suo pid come riferimento storico interessante — utile per l'analisi del registro, ad esempio.

system LIST
system PROGRAM LIST

fa esattamente la stessa cosa di exec LIST, tranne che un fork è fatto prima e il processo genitore aspetta che il processo figlio per uscire & hellip;

Se si desidera che il pid di entrambi script.pl e newscript.pl, fork e gestire la loro vita da soli. Con informazioni più specifiche sul problema che si sta affrontando, ’, potremmo darti suggerimenti più specifici.


Per bloccare altre istanze di un programma, una tecnica comune è quello di utilizzare il sistema operativo impianto ’ s per il blocco cooperativa: in fase di avvio, il tentativo di bloccare un certo file. Se ha successo, il tuo programma lo sa ’ s l'unico. Altrimenti, un altro processo ha già il blocco, quindi il nuovo processo viene chiuso. Vedi sotto per un esempio.

#! /usr/bin/env perl 

use strict; 
use warnings; 

use Fcntl qw/ :flock /; 
use File::Basename; 
use POSIX qw/ strftime /; 

$0 = basename $0; 

my $LOCK = "$ENV{HOME}/.lock-$0"; 

sub logmsg { 
    my($msg) = @_; 
    my $t = strftime "%F %T", localtime time; 
    warn "$0: $t - $$ - $msg\n"; 
} 

sub take_lock { 
    open my $fh, ">", $LOCK or die "$0: open $LOCK: $!"; 

    unless (flock $fh, LOCK_EX | LOCK_NB) { 
    logmsg "failed to lock $LOCK; exiting."; 
    exit 1; 
    } 

    $fh; 
} 

my $token = take_lock; 
logmsg "processing..."; 
sleep 2 * 60; 
logmsg "done."; 

Si noti che è necessario mantenere il filehandle tornato da take_lock aperta mentre il controllo è all'interno del vostro critical section. Il codice sopra lo considera come un token opaco. Alla chiusura del programma, Perl chiude il filehandle, che rilascia automaticamente il blocco. Quello che non vuoi fare è chiamare take_lock in un contesto vuoto perché questo eliminerebbe il tuo blocco.

+0

My script.pl esegue l'attività di pianificazione di altri script come newscript.pl e molti altri script. Non posso andare a programmarli direttamente in cron e quindi ho pensato di creare questo script genitore che avrebbe funzionato da schedulatore. Ora, ci può essere un caso in cui lo script pianificato viene ripetuto quando ottengo i nomi degli script dal database MySql, non voglio che lo script sia già in esecuzione per eseguirlo di nuovo e quindi stavo pensando se potevo catturare i PID degli script programmati, Posso verificare sulla base di questi Pid ed evitare l'esecuzione simultanea dello stesso script.Grazie a Ton per il tuo aiuto – Deepak

+0

C'è un altro modo per farlo senza usare la forcella? – Deepak

+0

Usa 'flock()' se hai bisogno di esclusività. 'usa Fcntl qw (: flock); flock ($ lockfd, LOCK_NB | LOCK_EX) o die "Lo stesso script sta già andando"; # ... 'Nota che $ lockfd è un descrittore di file e non un nome di file (devi aprirlo prima di flock). – Dallaylaen

9

Il numero di processo del processo corrente è $$. Utilizzare open3 anziché system per ricevere il numero di processo del processo figlio.

Problemi correlati