• Publicidad

Procesos Paralelos con Perl

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Procesos Paralelos con Perl

Notapor jc.morataya » 2009-08-04 20:56 @914

¡Hola!
Buenas,

Tengo dos preguntas que me gustaría saber si alguien puede ayudarme,

1) Tengo un script de Perl que despliega una GUI hecha con Win32::GUI y WIN32::GUI:Grid; en uno de los procesos estoy utilizando un ciclo infinito que va más o menos así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
while (1) {
   if (condicion) {
       $Grid->Refresh();
   } else {
        ...
   }
}
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Como ven, dentro del if() estoy haciendo un $Grid->Refresh() para redibujar todas las celdas del Grid, pero no lo consigo... ¿qué puedo hacer para actualizar los datos que caen en el grid durante el proceso infinito?

2) En el mismo script, me gustaría hacer algo que rompa el ciclo infinito con un botón, es decir, que el mismo botón active y desactive el ciclo infinito... de ahí lo de los procesos paralelos ya que en un proceso estaría el while(1) (ciclo infinito) y en el otro se le permitiría al usuario pinchar el botón para parar este ciclo de manera paralela... ¿cómo hago esto?

¡Muchas gracias a todos y un saludo!

JC
Última edición por explorer el 2009-08-06 09:20 @431, editado 1 vez en total
Razón: Ortografía, bloques de código
jc.morataya
Perlero nuevo
Perlero nuevo
 
Mensajes: 33
Registrado: 2008-02-28 09:30 @438

Publicidad

Re: Procesos Paralelos con Perl

Notapor jc.morataya » 2009-08-07 10:51 @494

Hola amigos,

Creo que no me dí a entender bien... ya que no he visto respuestas, pero investigando un poco creo que puedo arreglar esto haciendo un fork() en mi script.

Gracias de todas formas,

Saludos
jc.morataya
Perlero nuevo
Perlero nuevo
 
Mensajes: 33
Registrado: 2008-02-28 09:30 @438

Re: Procesos Paralelos con Perl

Notapor explorer » 2009-08-07 12:36 @566

Yo creo que no deberías utilizar un bucle infinito, porque puedes comerte todos los recursos de la CPU.

Es mejor usar un timer o temporizador, algo así como el sleep() del Perl, pero con una llamada al sistema gráfico de Windows, para que el sistema tenga la oportunidad de hacer cambios de contexto entre aplicaciones.

Actualización: Encontré un hilo que habla de Win32::Sleep.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Procesos Paralelos con Perl

Notapor jc.morataya » 2009-08-07 13:04 @586

Gracias, explorer, voy a intentarlo con sleep().

En este mismo contexto, fíjate que estoy haciendo un cronómetro de conteo regresivo en Perl. Tiene tres botones: "Correr","Detener","Reiniciar"; para el caso del botón "Correr", estoy usando esta subrutina:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. sub Run_Click {
  2.         print "Corre el Cronómetro...\n";
  3.         $Cero = "0";
  4.         for ($i = 5; $i >= 0; $i--) {
  5.                 for ($j = 59; $j >= 0; $j--) {
  6.                         # Minutos
  7.                         if ($i <= 9) {
  8.                                 $Mins = $Cero."".$i;
  9.                         } else {
  10.                                 $Mins = $i;
  11.                         }
  12.                         # Segundos
  13.                         if ($j <= 9) {
  14.                                 $Secs = $Cero."".$j;
  15.                         } else {
  16.                                 $Secs = $j;
  17.                         }
  18.                         $timevar = $Mins.":".$Secs;
  19.                         print "$timevar\n";
  20.                         sleep(1);
  21.                 }
  22.         }
  23. }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


El problema es que cuando ésta se ejecuta, el proceso se queda en las funciones for() que corren el cronómetro y no me permite en la GUI pinchar los botones "Detener" y "Parar"... Lo que creo es que hay que hacer algo con fork() para crear otros procesos que permitan usar estos otros botones... si es así, ¿cómo lo hago...? si no es así o si hay otra forma más fácil, ¿cuál sería?

Muchas gracias por la siempre efectiva ayuda,

Un saludo.
jc.morataya
Perlero nuevo
Perlero nuevo
 
Mensajes: 33
Registrado: 2008-02-28 09:30 @438

Re: Procesos Paralelos con Perl

Notapor explorer » 2009-08-07 13:38 @610

Debes usar Win32::Sleep, como te comento en la actualización del mensaje anterior.

En la documentación de Win32, busca por Sleep. Verás que pone que, mientras espera tu programa, Sleep da opciones a Windows a responder a eventos.

Ahora no sé decirte si Win32::GUI dispone de algo parecido, pero yo creo que sí.

Actualización: Aquí está: Win32::GUI::Tutorial::Part4::Timers. De todas maneras, si tu programa está haciendo cuentas constantemente, entonces no estamos hablando de hacer esperas. Lo que quieres es, realizar cuentas, presentarlas y al mismo tiempo, que el programa responda a eventos Windows que le lleguen. La solución es hacer un sleep de 0 segundos dentro del bucle: de esta manera tu programa no espera, pero, lo importante, le da la oportunidad a Windows a responder a eventos.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Procesos Paralelos con Perl

Notapor jc.morataya » 2009-08-07 14:42 @654

Perlfecto... funcionó muy bien, lo he solucionado con la función addtimer() del Win32::GUI. Muchas gracias, explorer,

Un saludo cordial.
jc.morataya
Perlero nuevo
Perlero nuevo
 
Mensajes: 33
Registrado: 2008-02-28 09:30 @438

Re: Procesos Paralelos con Perl

Notapor explorer » 2009-08-09 13:23 @599

Sería interesante ver un ejemplo muy pequeño de esto... para que quedase claro cómo hacerlo.
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Procesos Paralelos con Perl

Notapor jc.morataya » 2009-08-10 11:31 @521

Hola,

El que sigue es el código de un simple pero funcional cronómetro hecho con Perl. Aún requiere algunos ajustes pero funciona bastante bien, está basado en el uso de Timers disponibles en la distribución corriente del Win32::GUI...

Cualquier comentario de mejora es bienvenido...

¡Ciao!

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #! perl
  2. #
  3. #  Cronómetro
  4.  
  5. #use strict  # activa esto pero antes tienes que hacer los arreglos necesarios...
  6. use Win32::GUI;
  7.  
  8. my $Window;
  9. my $Zero = "0";
  10. my $i = 60;
  11. my $Resetting = 0;
  12.  
  13. # Parámetros del Cronómetro
  14. my $MinuteParam = 1; # Acá pones los minutos que quieras que corra tu cronómetro...
  15. $MinuteParam = $MinuteParam - 1;
  16. my $j = $MinuteParam;
  17.  
  18. # Ventana principal del cronómetro
  19. $Window = Win32::GUI::Window->new (
  20.     -title  => "Cronometro Perl",
  21.     -left   => 270,
  22.     -top    => 10,
  23.     -width  => 250,
  24.     -height => 200,
  25.     -name   => "Window",
  26. ) or die "Window";
  27.  
  28. # Fuente con tamaño 14 y negrita
  29. $Font = Win32::GUI::Font->new(
  30.               -name => "Font",
  31.               -size => 14,
  32.               -bold => 1,
  33. );
  34.  
  35. # La etiqueta donde se despliega el tiempo del cronómetro
  36. $initimevar = IniTimeVar($j);
  37. $Window -> AddLabel(
  38.                     -name   => "timex",
  39.                     -pos    => [10,10],
  40.                     -height => 30,
  41.                     -width  => 250,
  42.                     -font   => $Font,
  43.                     -text   => "$initimevar",
  44. ) or die "new Label";
  45.  
  46. # Correr el Cronometro
  47. $Run =  $Window ->AddButton(
  48.                     -name => "Run",
  49.                     -pos  => [ 25, 95 ],
  50.                     -width    => 60,
  51.                 -height   => 30,
  52.                 -text     => 'Correr',
  53. );
  54.  
  55. # Resetear el Cronómetro
  56. $Reset =  $Window ->AddButton(
  57.                     -name => "Reset",
  58.                     -pos  => [ 90, 95 ],
  59.                     -width    => 60,
  60.                 -height   => 30,
  61.                 -text     => 'Resetear',
  62. );
  63.  
  64. # Detener el Cronómetro
  65. $Stop =  $Window ->AddButton(
  66.                     -name => "Stop",
  67.                     -pos  => [ 155, 95 ],
  68.                     -width    => 60,
  69.                 -height   => 30,
  70.                 -text     => 'Detener',
  71. );
  72.  
  73. # Aquí está en timer
  74. $t1 = $Window->AddTimer('T1', 1000);
  75.  
  76. # Lo de cajón para que esto funcione bien...
  77. $Window->Show;
  78. $Window->Center;
  79. Win32::GUI::Dialog();
  80.  
  81.  
  82. # ================================================================
  83. # Subrutinas
  84. # ================================================================
  85. sub Window_Terminate {
  86.         $Window->Hide();
  87.         return -1;
  88. }
  89.  
  90. sub Run_Click {
  91.         $t1 = $Window->AddTimer('T1', 1000);
  92. }
  93.  
  94. sub Reset_Click {
  95.         $i = 60;
  96.         $j = $MinuteParam;
  97.         $t1->Interval(0);
  98.         $i --;
  99.     $initimevar = IniTimeVar($j);
  100.         $Window->timex->Change( -text => $initimevar);
  101.         $Window->timex->Update();
  102. }
  103.  
  104. sub Stop_Click {
  105.         $t1->Interval(0);
  106. }
  107.  
  108. sub T1_Timer {
  109.         if ($Resetting == 1) {
  110.                 $i = 59;
  111.                 $j = $MinuteParam;
  112.         $timevar = IniTimeVar($j);
  113.                 $Window->timex->Change( -text => $timevar);
  114.                 $Window->timex->Update();
  115.                 $Resetting = 0;
  116.     } else {
  117.             $i--;
  118.                 if ($i == 0) {
  119.                         $j--;
  120.                     $i = 59;
  121.                     if ($j == -1) {
  122.                             $t1->Kill();
  123.                             $i = 0;
  124.                             $j = 0;
  125.                             $Resetting = 1;
  126.                      }
  127.                 }
  128.             # Segundos
  129.                 if ($i <= 9) {
  130.                         $Secs = $Zero."".$i;
  131.                 } else {
  132.                         $Secs = $i;
  133.                 }
  134.                 # Minutos
  135.                 if ($j <= 9) {
  136.                         $Mins = $Zero."".$j;
  137.                 } else {
  138.                         $Mins = $j;
  139.                 }      
  140.                 $timevar = $Mins.":".$Secs;
  141.                 $Window->timex->Change( -text => $timevar);
  142.                 $Window->timex->Update();
  143.     }
  144. }      
  145.  
  146. sub IniTimeVar {
  147.         $jj = $_[0];
  148.         $jj = $j + 1;
  149.         if ($j <= 9) {
  150.                 $initimevar = $Zero."".$jj.":".$Zero."".$Zero;
  151.         } else {
  152.                 $timevar = $jj.":".$Zero."".$Zero;
  153.         }
  154. }
  155.  
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4
Última edición por explorer el 2009-08-10 16:28 @727, editado 1 vez en total
Razón: Acentos
jc.morataya
Perlero nuevo
Perlero nuevo
 
Mensajes: 33
Registrado: 2008-02-28 09:30 @438

Re: Procesos Paralelos con Perl

Notapor jc.morataya » 2009-08-11 13:07 @588

Pues no es un pequeño ejemplo, sino más bien todo el código. Igual creo que le vendrá bien a alguien que quiera usar los "timers" del Win32::GUI.

Saludos y ¡gracias por la siempre excelente ayuda!
jc.morataya
Perlero nuevo
Perlero nuevo
 
Mensajes: 33
Registrado: 2008-02-28 09:30 @438


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron