2012-02-09 22 views
6

He descubierto Perl bifurcación recientemente y estoy muy enamorado. Pero una cosa me preocupa: si solo estoy dividiendo procesos de izquierda a derecha, seguramente esto causará algún problema en alguna parte. ¿Hay algún tipo de control razonable que uno deba usar para asegurarse de que mi pequeña aplicación no consuma todos los recursos de mi máquina?Perl - horquilla responsable

Tome este código de ejemplo:

foreach my $command (@commands) { 
    my $pid = fork(); 
    if (!$defined $pid) { 
    #Fork failed. Do something. 
    } elsif ($pid == 0) { #This is the child. 
     system($command); 
     exit(0) 
    } 
} 

while (wait() != -1) {} #wait() will be -1 when the last child exits. 

Así que esto va a funcionar bien, y desovar en marcha un proceso para manejar cada comando. Todo sucederá en paralelo, lo cual es genial si estos comandos son completamente independientes.

¿Qué pasa si de repente tengo 5000+ comandos para ejecutar? No sería prudente desviar sin pensar esos muchos procesos. Entonces, ¿qué tipo de control debería implementarse y cómo?

)

+1

Um, mantener un registro de cuántas has bifurcada, y parar en un máximo entonces, ¿no matas a la máquina y tienes un administrador del sistema muy pronto enojado que se despierta a las 3 de la mañana? ;) –

+0

Bien, pero ¿qué es un "máximo" razonable? – Jeremy

+2

Es tonto llamar 'system' donde lo hiciste. 'system' es básicamente' fork' + 'exec' (child) +' waitpid' (parent). Cambiar 'system' a' exec'. – ikegami

Respuesta

7

Además, si usted está preocupado por el desove demasiados procesos bifurcados, al mismo tiempo, puede estrangular a ellos.

O bien haga su propio (utilizando una cola para mantener "a la horquilla"), o mejor aún, utilice el módulo Parallel::ForkManager que le permite limitar las horquillas simultáneas a través de un parámetro de constructor.

use Parallel::ForkManager; 
$pm = new Parallel::ForkManager($MAX_PROCESSES); 

Tenga en cuenta que se ForkManager también se ocupan de cosechar los procesos secundarios finalizados para usted a través de un proporcionadas "*" API esperar

+0

¡Esto parece ser el camino a seguir! Gracias. – Jeremy

3

Cuando un niño sale que va a enviar de vuelta un SIG_CHLD a los padres. Querrás cosechar esto como si no fuera zombies en la tabla de proceso hasta esa llamada final al wait al final de tu script.

Chapter 16 of O'Reilly's Perl Cookbook on Google books proporciona un montón de información sobre esto. Básicamente, necesita incrementar un contador cuando está bifurcando a los niños, y disminuirlo cuando los está cosechando, y no bifurcar nuevos que superen un máximo razonable de los niños que se están ejecutando actualmente.

En cuanto a lo que es un "máximo razonable" ... depende del hardware, y lo que están haciendo esos procesos bifurcados. No hay una respuesta estática a esa pregunta, excepto para probar lo que está haciendo y observar el impacto en el rendimiento de la máquina. Preferiblemente durante el horario comercial. Después de decirle al administrador de sistemas lo que estás haciendo. Él/ella puede incluso tener algunos consejos.

+0

No haga enlaces a reproducciones no autorizadas de material protegido por derechos de autor. –

+1

Ok, voy a vincular exactamente lo mismo en los libros de Google. –

1

Para asegurarse de que usted no generar más procesos que lo que el sistema puede manejar de manera eficiente puede utilizar módulos como Parallel::ForkManager

0

desove (bifurcar) tantos procesos como su sistema puede soportar se denomina fork bomb. Es posible que su sistema se congele o se bloquee a medida que su tabla de procesos se sature y la memoria y la CPU se agoten. En los sistemas Linux, el comando ulimit debe mostrar la cantidad máxima de procesos de usuario permitidos. Puede (debería) configurar esto de manera apropiada para su sistema. Bifurcar crea procesos exponencialmente. Por lo tanto, este fragmento crear cuatro procesos que consumen CPU sin fin hasta que mató a un desagradable ---, pequeña bomba:

perl -e 'fork; fork; 1 while {}' 
Cuestiones relacionadas