Lun Jun 25, 2007 5:33 pm
|
 |
creating021
Vive para Perl en Español

|
Registrado: 23 Feb 2006
Mensajes: 498
Ubicación: Frente al monitor
|
|
| Problema con threads al hacer un servidor. |
|
|
Hola.
Siguiendo el recipiente 17.14 de Perl CookBook (2nd edition) de hacer un servidor multitasking (uso Sockets y no IO::Sockets por algunos problemas y limitaciones).
La cosa es que al usarlo ciertas veces el servidor muere... sin dar error alguno.
El código es muy similar al del libro (la parte de thread es 100% igual) y me pregunto sí el problemas es threads y si es bueno hacerlo con threads.pm o si hay mejor forma de hacerlo (sin usar POE).
Gracias. |
|
|
|

Lun Jun 25, 2007 5:44 pm
|
 |
creating021
Vive para Perl en Español

|
Registrado: 23 Feb 2006
Mensajes: 498
Ubicación: Frente al monitor
|
|
|
|
|
El prolbemas está en perldoc (al parecer es esto)
| Cita: | WARNINGS
A thread exited while %d other threads were still running
A thread (not necessarily the main thread) exited while there were still other threads running. Usually it's a good idea to first collect the return values of the created threads by joining them, and only then exit from the main thread. |
No se que hacer... |
|

Lun Jun 25, 2007 8:31 pm
|
 |
Perl user
Maestro Honorario

|
Registrado: 03 Nov 2004
Mensajes: 385
|
|
|
|
|
Que tal,
Bueno en primera instancia, no has publicado nada de código como para saber qué está REALMENTE mal, pero... te puedo casi asegurar que efectivamente SI es el thread principal el que está muriendo antes que los demás terminen, y esto es un comportamiento érroneo (es decir, de mal diseño) si los otros threads que están vivos no son daemons.
Lo que te dice el manual es correcto, ya que tu thread principal (o el que los lanzó a todos los que quedan vivos) de alguna manera tiene que esperar a que los otros terminen por medio de join().
El uso de threads.pm está realmente vetado puesto que baja considerablemente el performance del intérprete de Perl y también hace que muchos módulos (principalmente los de XS) fallen o tengan comportamientos indefinidos. Otra cosa importante es que multitasking es diferente a multi-threaded, hay muchas técnicas para realizar aplicaciones multitareas asíncronas, y ello implica incluso el uso de Poll/epoll, select, kselect, etc (Qué son algunos mecanismos de los que usa POE) y son muy eficientes puesto que los eventos son proporcionados directamente por el kernel.
Lo que te recomiendo, si todavía quieres algo como threads.pm, es que uses el pragma 'forks' que implementa todo lo que te ofrece threads.pm, pero utilizando como el nombre lo indica, la llamada al sistema fork.
Lamentablemente el manejo de múltiples threads en Perl sigue teniendo un mal desarrollo y todavía está muy verde, y es por eso que se recomienda evitar su uso, los ithreads existen con el propósito de emular fork() y afines en sistemas Win32, pero no para generar aplicaciones multi-thread en producción.
Así que bueno, la recomendación es: usa forks o usa POE; POE sigue siendo la mejor opción, a menos que REALMEMENTE tu implementación necesite de un thread/fork.
Saludos, |
|

Sab Jun 30, 2007 3:28 pm
|
 |
creating021
Vive para Perl en Español

|
Registrado: 23 Feb 2006
Mensajes: 498
Ubicación: Frente al monitor
|
|
|
|
|
| Perl: | use threads;
use IO:: Socket;
my $listen = IO:: Socket:: INET-> new(
LocalPort => 80,
ReuseAddr => 1,
Listen => 10,
);
sub handle_connection {
my $socket = shift;
#código y más código...
}
while(my $socket = $listen-> accept){
async (\&handle_connection, $socket)-> detach;
} |
Bueno, el código es similar (como ya dije, estoy usando Socket y no IO::Socket).
Y según mi libro (Computer Science & Perl Programming) no es una buena idea por el tema de ports a otros OS (como Win32 y preOS X).
Supongo que lo mejor es hacerlo con fork... pero me surge una duda:
Viendo el código de Perl CoockBook (nueva mente) noto que usa POSIX.
¿Si lo hago así, sería portable a Win32 y OS X?
Gracias por los comentarios. |
|

Dom Jul 01, 2007 11:51 am
|
 |
Perl user
Maestro Honorario

|
Registrado: 03 Nov 2004
Mensajes: 385
|
|
|
|
|
| creating021 escribió: | | Perl: | use threads;
use IO:: Socket;
my $listen = IO:: Socket:: INET-> new(
LocalPort => 80,
ReuseAddr => 1,
Listen => 10,
);
sub handle_connection {
my $socket = shift;
#código y más código...
}
while(my $socket = $listen-> accept){
async (\&handle_connection, $socket)-> detach;
} |
Bueno, el código es similar (como ya dije, estoy usando Socket y no IO::Socket).
Y según mi libro (Computer Science & Perl Programming) no es una buena idea por el tema de ports a otros OS (como Win32 y preOS X).
Supongo que lo mejor es hacerlo con fork... pero me surge una duda:
Viendo el código de Perl CoockBook (nueva mente) noto que usa POSIX.
¿Si lo hago así, sería portable a Win32 y OS X?
Gracias por los comentarios. |
Mira... la elección de usar Socket e IO::Socket es realmente sin importancia, no creo que estés desarrollando una aplicación de misión crítica como para que el 0.02% de overhead de IO:Socket sobre Socket tenga alguna importancia. IO::Socket es solo un wrapper sobre Socket, el cual es a su vez un wrapper sobre bsd sockets
Y según tu libro, el cuál también tengo, no es buena idea qué? Si hablas de una llamada fork(), fork es accesible en cualquier sistema tipo UNIX, y está implementado para sistemas que no lo soportan por medio de cuestiones como ithreads (por eso es costoso...), así que... ESO es portable.
Y no sé a qué recipe del Perl Cookbook te refieres, pero yo hablaba de forks, el pragma, no fork() la llamada al sistema. Lee nuevamente mi comentario y verifica por qué mencioné forks (como pragma).
Otra alternativa es utilizar Coroutines, alternativa muy buena para eventos asíncronos, que no requiere de sincronización ni locking.
Saludos, |
|

Dom Jul 01, 2007 1:42 pm
|
 |
creating021
Vive para Perl en Español

|
Registrado: 23 Feb 2006
Mensajes: 498
Ubicación: Frente al monitor
|
|
|
|
|
| Perl_user escribió: | | Mira... la elección de usar Socket e IO::Socket es realmente sin importancia, no creo que estés desarrollando una aplicación de misión crítica como para que el 0.02% de overhead de IO:Socket sobre Socket tenga alguna importancia. IO::Socket es solo un wrapper sobre Socket, el cual es a su vez un wrapper sobre bsd sockets |
Solo quería aclarar las diferencias y tienes mucha razón en esto, realment no importa.
| Perl_user escribió: | | Y según tu libro, el cuál también tengo, no es buena idea qué? Si hablas de una llamada fork(), fork es accesible en cualquier sistema tipo UNIX, y está implementado para sistemas que no lo soportan por medio de cuestiones como ithreads (por eso es costoso...), así que... ESO es portable. |
No, no fork, Threads.pm en Perl 5.005_03... no lo aclaré (notese, Threads y no treads).
La pregunta era para POSIX, pero ya que no lo uso, no importa... de todos modos encontré (ya no tengo el link) lo que si y no era soportado en diferentes OS las funciones de POSIX.
| Perl_user escribió: | | Y no sé a qué recipe del Perl Cookbook te refieres, pero yo hablaba de forks, el pragma, no fork() la llamada al sistema. Lee nuevamente mi comentario y verifica por qué mencioné forks (como pragma). |
17.algo, uno que usa fork() y POSIX...
Resulta que solucioné el problema con fork(), sin POSIX y actualmente funciona sin problema.
Cualquier módulo (de los que has nombrados) logran la facilidad de programar el servidor con muy buena calidad.
Muchas gracias por todo esto, me ha sido de mucha ayuda. |
|

Powered by phpBB © 2001, 2005 phpBB Group
|