• Publicidad

Ayuda con threads

¿Ya sabes lo que es una referencia? Has progresado, el nível básico es cosa del pasado y ahora estás listo para el siguiente nivel.

Ayuda con threads

Notapor z1rr0s1s » 2010-11-18 19:08 @839

¡Hola, muy buenas!

Llevo un tiempo programando en Perl y nunca me ha venido la necesidad de utilizar threads.

Hoy, haciendo un miniscript sencillo me vino la idea de utilizarlos para realizar el proceso más rápido. Me puse a buscar sobre ello y a leer y la verdad es que no me entero muy bien cómo funcionan.

A ver si me podéis echar una mano ; - )

Mi idea es la siguiente:

A partir de un dominio dado al script, cargará una lista de palabras para utilizarlas como subdominio; a cada subdominio formado realizará una petición A, y si ésta es exitosa lo apuntará.

Mi idea es que se pueda definir en una variable el número máximo de threads y que cada thread realice la petición al subdominio formado. Ésto me interesa por si se le pasa al script una lista grande de palabras, que tarde menos.

Aquí pego lo que tengo hecho:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -W
  2.  
  3. use Net::DNS ;
  4. use threads ;
  5.  
  6. my $domain = 'apple.com' ;
  7. my $wordlist = 'wordlist.txt' ;
  8. my $max_threads = 10 ;
  9.  
  10. _checksdomain ( $domain );
  11.  
  12. sub _as {
  13.         my $domain = shift ;
  14.  
  15.         my $resolv  = Net::DNS::Resolver->new() ;
  16.         my $query = $resolv->query( $domain, 'A' );
  17.  
  18.         if ( $query ){
  19.                 foreach ( $query->answer ){
  20.                         return $_->string ;
  21.                 }
  22.         }
  23. }
  24.  
  25. sub _checksdomain
  26. {
  27.         open(WORDL, $wordlist) || die "[-] ERROR: ".$!,"\n" ;
  28.         while(<WORDL>){
  29.                 chomp ;
  30.                 $bdomain = $_.".".$domain ; # PALABRA.DOMINIO
  31.  
  32.                 # CREAR THREADS PARA QUE SE COMPRUEBE CADA DOMINIO CON UNO Y REALICE EL PROCESO MÁS RÁPIDO
  33.  
  34.                 print _as( $bdomain ),"\n" if _as( $bdomain ) ;
  35.         }
  36.         close(WORDL);
  37. }
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4


Un saludo y gracias de antemano.

P.D: Muy bueno el foro, hacen un gran trabajo ayudando a la gente con este gran lenguaje :D
z1rr0s1s
Perlero nuevo
Perlero nuevo
 
Mensajes: 6
Registrado: 2010-11-18 18:03 @793

Publicidad

Re: Ayuda con threads

Notapor explorer » 2010-11-19 07:55 @371

Bienvenido a los foros de Perl en Español, z1rr0s1s.

Hay pocas discusiones en estos foros que hablen de los threads. Yo, particularmente, prefiero usar fork().

Usa el sistema de búsqueda para encontrar esas discusiones.
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: Ayuda con threads

Notapor z1rr0s1s » 2010-11-19 11:05 @503

He estado mirándome un poco las discusiones del foro, pero no consigo ver cómo repartir el trabajo entre los procesos hijos.

¿Qué diferencia hay entre el módulo threads y el uso de fork()?

Hice algo así, pero no consigo ver cómo lo podría aplicar a mi pequeño script. El script me lo mandaron realizar en mi trabajo sin threads, ni nada por el estilo, pero me interesa añadirle esto para que sea más rápido.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. @array = qw(perro gato pollo gallina);
  4.  
  5. $num = 5 ;
  6.  
  7. foreach (@array){
  8.         for( my $i = 1; $i<=$num; $i++ ){
  9.                 my $pid = fork();
  10.                 if ($pid) {
  11.                         # parent
  12.                         waitpid($pid,0) ;
  13.                 } elsif ($pid == 0) {
  14.                         print $_,"\n";
  15.                         exit(0);
  16.                 }
  17.                 else {
  18.                         die "couldn’t fork: $!\n";
  19.                 }
  20.         }
  21. }
  22. print "FOR OUT\n";
  23.  
  24. __END__
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Me devuelve:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
z1rr0@deb:~/Desktop$ perl a.pl
perro
perro
perro
perro
perro
gato
gato
gato
gato
gato
pollo
pollo
pollo
pollo
pollo
gallina
gallina
gallina
gallina
gallina
FOR OUT
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4



Un saludo.
z1rr0s1s
Perlero nuevo
Perlero nuevo
 
Mensajes: 6
Registrado: 2010-11-18 18:03 @793

Re: Ayuda con threads

Notapor explorer » 2010-11-19 17:44 @780

El problema que hay en el código es que, mientras el hijo está ocupado en pintar el texto, el padre, que debería estar lanzando más hijos, en realidad le estás pidiendo que espere al hijo, al llamar al waitpid().

Si lo cambias un poco, salen cosas distintas:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. my @array = qw(perro gato pollo gallina);
  6. my $num = 5 ;
  7. my $pid;
  8.  
  9. foreach (@array) {
  10.     for( my $i = 1; $i<=$num; $i++ ) {
  11.         $pid = fork();
  12.         if ($pid == 0) {
  13.             # hijo
  14.             sleep 1+rand 10;
  15.             print $_,"\n";
  16.             exit(0);
  17.         }
  18.     }
  19. }
  20.  
  21.  
  22. print "FOR OUT\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

El módulo Parallel::ForkManager simplifica mucho todo esto.

En cuanto al aumento de velocidad que quieres conseguir, depende solamente del número de procesadores/núcleos que tengas en tu ordenador. Piensa: aunque lances 20 hijos, y solo tengas un procesador, tardarás lo mismo que si lo ejecutas de modo secuencial (bueno, en realidad tardarás más, debido al tiempo consumido en los cambios de contexto).
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: Ayuda con threads

Notapor z1rr0s1s » 2010-11-21 16:11 @716

Esto es lo que me tira de salida:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
gallina
gallina
gato
perro
pollo
gato
pollo
gallina
pollo
perro
perro
gato
gallina
perro
gallina
pollo
gato
gato
pollo
perro
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


¿Es posible hacer que cada elemento del array lo procese un proceso hijo?

Me interesaría aprender a hacerlo sin usar ningún módulo adicional.

¿El módulo que me mencionaste utiliza threads? Lo que quiero podría ser así, ¿no?

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -W
  2.  
  3. use Parallel::ForkManager;
  4.  
  5. my $max_process = 10 ;
  6. my @array = qw(perro gato pollo gallina);
  7.  
  8. $pm = new Parallel::ForkManager($max_process);
  9.  
  10. foreach $data (@array) {
  11.         my $pid = $pm->start and next;
  12.         print $data,"\n";
  13.         $pm->finish;    # ACABAR PROCESO
  14. }
  15. $pm->wait_all_children; # ESPERAR A QUE ACABEN TODOS LOS HIJOS
  16.  
  17. __END__
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
z1rr0s1s
Perlero nuevo
Perlero nuevo
 
Mensajes: 6
Registrado: 2010-11-18 18:03 @793

Re: Ayuda con threads

Notapor explorer » 2010-11-21 17:48 @783

z1rr0s1s escribiste:¿Es posible hacer que cada elemento del array lo procese un proceso hijo?
Eso es lo que está haciendo...

z1rr0s1s escribiste:Me interesaría aprender a hacerlo sin usar ningún módulo adicional.
Pues entonces te queda leer la documentación referente a fork() y threads. Y un día, cuando te des cuenta de lo útil que son los módulos, quizás quieras aprender POE (web), que tiene unas características muy interesantes, para multitarea.

z1rr0s1s escribiste:¿El módulo que me mencionaste utiliza threads?
Como su nombre indica, usa fork().

z1rr0s1s escribiste:Lo que quiero podría ser así, ¿no?
¿Lo has probado? A mi me parece que es correcto. Cada vez que llamas a start() estás creando un nuevo proceso, que ejecutará lo que sigue. Y wait_all_children() esperará por todos.

Mira, si lees el código de ForkManager puedes aprender mucho sobre fork() :)
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: Ayuda con threads

Notapor explorer » 2010-11-21 17:58 @790

z1rr0s1s escribiste:¿Qué diferencia hay entre el módulo threads y el uso de fork()?

Bueno, lo normal es leer, por ejemplo en la Wikipedia, las definiciones de Hilo de ejecución y de Bifurcación (sistema operativo).

En resumen. Hilo: «Los distintos hilos de ejecución comparten una serie de recursos tales como el espacio de memoria, los archivos abiertos, situación de autenticación, etc.»

Bifurcación: «hace referencia a la creación de una copia de sí mismo por parte de un programa, que entonces actúa como un "proceso hijo" del proceso originario, ahora llamado "padre". Los procesos resultantes son idénticos, salvo que tienen distinto número de proceso (PID).»
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: Ayuda con threads

Notapor z1rr0s1s » 2010-11-21 18:27 @810

Muchas gracias por las respuestas, explorer, estoy aprendiendo bastante.

Lo que me estoy dando cuenta es que es más rápido el script de forma secuencial que haciendo bifurcaciones.

¿En qué casos recomendarías utilizar bifurcaciones?

¡Un saludo!
z1rr0s1s
Perlero nuevo
Perlero nuevo
 
Mensajes: 6
Registrado: 2010-11-18 18:03 @793

Re: Ayuda con threads

Notapor explorer » 2010-11-21 18:34 @815

Cuando el proceso necesite mucho procesamiento/cálculo de CPU, y ejecutando tantas bifurcaciones como núcleos de procesador. No más. De hecho, siempre suelo dejar un núcleo libre para el resto de programas y las tareas propias del sistema operativo.
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: Ayuda con threads

Notapor z1rr0s1s » 2010-11-22 10:58 @498

Muchas gracias, en este caso creo que no utilizaré bifurcaciones ni hilos, pero para la próxima ya sabré.

Estaría interesado en que este script y posteriores creen un fichero de registro con lo que obtengan. ¿Qué formato me recomendarías para que después ese fichero pueda ser interpretado por otras aplicaciones?

Saludos
z1rr0s1s
Perlero nuevo
Perlero nuevo
 
Mensajes: 6
Registrado: 2010-11-18 18:03 @793

Siguiente

Volver a Intermedio

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 16 invitados

cron