Página 1 de 1

Ejecutar procesos simultaneos

NotaPublicado: 2012-04-24 22:41 @987
por poeaod
Hola a todos los monjes.

Hace ya un año y medio que por primera vez vi lo que era Perl (y agradezco a Larry Wall).
Tanto fue que me gustó, que trato de usarlo para todo, sí... todo.

En esta ocasión me encuentro muy trabado con lo siguiente:

Necesito un programa que ejecute dos procesos al mismo tiempo.
Googlee y googlee y no doy en la tecla.
Entiendo que lanzar varios procesos recursivos (que no tienen un final) desde un script en Perl es lo que se llama fork().

Lamentablemente no logro entender los ejemplos.

En mi caso es lo siguiente:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. use warnings;
  4.  
  5. suma();
  6. resta();
  7.  
  8. sub suma
  9. {
  10.   $i=1;
  11.   while ($i>=0)
  12.         {
  13.           print "$i\n";
  14.           $i++;
  15.         }
  16. }
  17.  
  18. sub resta
  19. {
  20.   $i=0;
  21.   while ($i<=0)
  22.         {
  23.           print "$i\n";
  24.           $i=$i-1;
  25.         }
  26. }
  27.  
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4



En el ejemplo anterior tengo dos funciones (subprocesos) recursivas, es decir que no van a terminar, que necesito se lancen independientemente una de otra simultáneamente.

¿¿¿Alguien me puede orientar???

Desde ya, mil gracias.

PD: El script anterior lo hice para el ejemplo, en la realidad las dos funciones interpretan los logs de servidores. Las hice así para acotar, son muchísimas líneas de código, sino.


¡¡¡Mil graciasss!!!

Re: Ejecutar procesos simultaneos

NotaPublicado: 2012-04-25 11:04 @503
por explorer
A ver si con este ejemplo te ayuda a entender el proceso de fork()
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/env perl
  2. use v5.14;
  3.  
  4. sub suma {
  5.     for (1 .. 10) {
  6.         say;
  7.         sleep rand 5;
  8.     }
  9. }
  10.  
  11. sub resta {
  12.     for (reverse -10 .. -1) {
  13.         say;
  14.         sleep rand 5;
  15.     }
  16. }
  17.  
  18. my $es_el_hijo = fork();
  19.  
  20. die "ERROR: No pude reproducirme: $!\n"
  21.     if not defined $es_el_hijo;
  22.  
  23. if ($es_el_hijo) {                      # Si sabemos quién es nuestro hijo, es que somos el padre
  24.     say "Nuestro hijo tiene el número $es_el_hijo";
  25.    
  26.     suma();                             # Trabajo del proceso padre
  27.  
  28.     while ('Muerte y destrucción') {    # Esperamos la muerte de nuestros hijos
  29.         say "...";
  30.  
  31.         my $hijo_muerto = wait;
  32.  
  33.         last if $hijo_muerto == -1;     # No hay que esperar por más muertes
  34.  
  35.         my $estado = $? >> 8;           # Consultar system() para ver el significado de $?
  36.  
  37.         say "Murió el hijo [$hijo_muerto] con estado [$estado]";
  38.     }
  39. }
  40. else {                                  # Si no somos el padre, somos el hijo
  41.     resta();                            # Trabajo del proceso hijo
  42.  
  43.     exit 2;                             # salimos, informando del estado
  44. }
  45. __END__
  46.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Hay módulos que facilitan la generación de procesos, como Parallel::ForkManager (busca en CPAN por 'fork').

Naturalmente, también depende del sistema operativo en que te encuentres. Si es un sistema que no implementa la función fork(2), entonces deberías leer el documento perlfork.

Re: Ejecutar procesos simultaneos

NotaPublicado: 2012-04-25 12:23 @558
por poeaod
Sí, ejemplos similares encontré por la red, pero los procesos recurrentes no se lanzan en simultáneo.

¿Perl permite ejecutar dos procesos (subprocesos, o sea, escritos dentro del mismo script) en simultáneo?

Por ahí no me expliqué bien. La idea es ejecutar estos dos subprocesos al mismo tiempo y que no terminen nunca.

PD:
Estoy en un entorno Windows.

Me fijé con "threads", pero tampoco pude.

Re: Ejecutar procesos simultaneos

NotaPublicado: 2012-04-25 14:54 @663
por explorer
¿No se lanzan en paralelo? En mi ordenador sí.

¡¡¡Aaahh!!! que -aún- estás en Windows... eso lo explica todo ;)

El fork() en Windows es algo especial. Depende mucho de la versión Perl que estés usando. En las últimas versiones, fork() en esos sistemas, lo que hace es clonar el intérprete perl, su estado, en un hilo distinto, y lo hace continuar después del punto en que fue llamado el fork() en el proceso padre.

Hay distribuciones especializadas en la gestión de tareas concurrentes (o pseudo-concurrentes), como por ejemplo Coro, pero antes debes consultar la matriz de compatibilidad.

Si nos ceñimos a lo que pides (dos trozos de código en el mismo programa), en CPAN hay un montón, como por ejemplo, subs::parallel, Parallel::Loops, Parallel::Simple, Parallel::Queue, Parallel::Runner...

Si nos das una pista de lo que quieres hacer en esas tareas, puede que encontremos una distribución específica, como por ejemplo Parallel::Downloader, Parallel::Simple::Dynamic, Parallel::Iterator...

Re: Ejecutar procesos simultaneos

NotaPublicado: 2012-04-25 19:22 @849
por poeaod
¡ja,ja! No, explorer, yo soy linuxero viejo. Pero muchos clientes tienen tecnología Windows, y como es tan cerrada, tengo que hacer mis propios servicios (con Perl).

Lo que tengo que hacer es eso mismo. Dos bucles simultáneos... La verdad, me vengo rompiendo la cabeza desde Enero, no es fácil, parece.

Re: Ejecutar procesos simultaneos

NotaPublicado: 2012-04-25 19:40 @861
por explorer
Que se ejecuten de forma simultánea, en Windows, yo lo veo muy difícil, sin que exista algún tipo de control de sincronización, salvo que nos digas que los procesos no necesitan estar sincronizados en lo que hacen, y basta conque arranquen a la vez.

Coro es una perfecta solución si quieres tener los procesos sincronizados. Lo que ya no sé es cómo se comportará en Windows.

Re: Ejecutar procesos simultaneos

NotaPublicado: 2013-07-28 02:13 @134
por explorer
Un posible intento sería también con IPC::Run.