2012-02-22 16 views
6

Estoy escribiendo un script Perl (digamos script.pl) que llama a otro script newscript.pl. Solo quiero obtener los PID de ambos scripts en script.pl. Puedo obtener el PID de script.pl mediante código¿Cómo obtengo el PID de un proceso creado con la función de sistema de Perl?

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

siguiente Después de esto que llamo system para ejecutar newscript.pl

system("perl newscript.pl"); 

Quiero capturar el PID genera por este newscript.pl en script.pl.

Respuesta

5

En el momento en que system regresa, el proceso engendrado ya habrá salido, dejando su pid como referencia histórica interesante — útil para el análisis de registros, por ejemplo.

system LIST
system PROGRAM LIST

hace exactamente lo mismo que exec LIST, excepto que una fork se hace primero y el proceso padre espera a que el proceso hijo para salir y hellip;

si desea que los PIDs de los dos script.pl y newscript.pl, fork y gestionar su vida sí mismo. Con información más específica sobre el problema que ’ está abordando, podemos darle sugerencias más específicas.


Para bloquear otras instancias de un programa, una técnica común es el uso de las instalaciones del sistema operativo ’ s para el bloqueo de cooperación: en el inicio, intenta bloquear un determinado archivo. Si tiene éxito, su programa lo sabe ’ s el único. De lo contrario, otro proceso ya tiene el bloqueo, por lo que el nuevo proceso finaliza. Vea abajo para un ejemplo.

#! /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."; 

Observe que debe mantener el gestor de archivo regresó de take_lock abierta mientras que el control está dentro de su critical section. El código anterior lo trata como un token opaco. Cuando su programa finaliza, Perl cierra el identificador de archivo, que libera el bloqueo automáticamente. Lo que no quiere hacer es llamar al take_lock en contexto vacío porque eso descartaría su bloqueo.

+0

Mi script.pl realiza la tarea de programar otros scripts como newscript.pl y muchos otros scripts. No puedo programarlos directamente en cron y, por lo tanto, pensé en hacer este script principal que actuaría como programador. Ahora, puede haber un caso cuando la secuencia de comandos programada se repite a medida que obtengo los nombres de secuencia de comandos de databse MySql, no quiero que la secuencia de comandos que ya se está ejecutando se ejecute de nuevo y por lo tanto estaba pensando si podría capturar los PID de scripts programados, Puedo verificar en base a estos Pids y evitar la ejecución simultánea del mismo script.Gracias a Ton por su ayuda – Deepak

+0

¿Hay alguna otra manera de hacerlo sin usar el tenedor? – Deepak

+0

Use 'flock()' si necesita exclusividad. 'use Fcntl qw (: flock); flock ($ lockfd, LOCK_NB | LOCK_EX) o muere "El mismo script ya está en marcha"; # ... 'Tenga en cuenta que $ lockfd es un descriptor de archivo y no un nombre de archivo (debe abrirlo antes del flock). – Dallaylaen

9

El número de proceso del proceso actual es $$. Use open3 en lugar de system para recibir el número de proceso del proceso secundario.

Cuestiones relacionadas