2010-07-20 14 views
9

Estoy tratando de tomar un programa Perl que escribí y enhebrarlo. El problema es que leí que algunos módulos no son "seguros para subprocesos". ¿Cómo puedo saber si un módulo es seguro para subprocesos? He buscado una lista y no puedo encontrar una.Perl Thread Safe Modules

para probar un módulo de uso frecuente (Texto :: CSV_XS) He probado el siguiente código a cabo:

use strict; 
use warnings; 
use threads; 
use threads::shared; 
require Text::CSV_XS; 

my $CSV = Text::CSV_XS->new ({ binary => 1, eol => "\n" }) or die("Cannot use CSV: ".Text::CSV->error_diag()); 
open my $OUTPUT , ">:encoding(utf8)", "test.csv" or die("test.csv: $!"); 

share($CSV); 

my $thr1 = threads->create(\&sayHello('1')); 
my $thr2 = threads->create(\&sayHello('2')); 
my $thr3 = threads->create(\&sayHello('3')); 


sub sayHello 
{ 
my($num) = @_; 

print("Hello thread number: $num\n"); 

my @row = ($num); 
    lock($CSV);{ 
    $CSV->print($OUTPUT, \@row); 
    $OUTPUT->autoflush(1); 
    }#lock 
}#sayHello 

La salida de recibo es la siguiente:

 
Hello thread number: 1 
Segmentation fault 

¿Significa esto el módulo no es seguro para subprocesos o es otro problema?

Gracias

+1

tratar de llegar con el programa más pequeño que puede que provoca el fallo de segmentación. – mob

Respuesta

32

En términos generales, los módulos básicos y de alta visibilidad son flujos seguros a menos que su documentación dice lo contrario.

Dicho esto, hay algunos pasos en falso en su puesto:

  1. share($CSV)
    Esto borra $CSV (un hashref bendita), just as documented in threads. En general, desea compartir() los objetos complejos antes de para la inicialización o, quizás en este caso, compartir () una variable tonta entre los hilos.
    Dado que $CSV mantiene el estado del XS subyacente, esto podría generar un comportamiento no definido.

    Pero esta no es su segfault.

  2. threads->create(\&sayHello('1'));
    Usted está invocando erróneamente sayHello(1) en el hilo principal y pasando una referencia a su valor de retorno a threads->create() como una (falsa) arranque de rutina. que quería decir:

    threads->create(\&sayHello, '1'); 
    

    Pero este no es su violación de segmento.

    (EDITAR sólo para aclarar - una rutina de inicio malo aquí no se arriesga a una SEGV en cualquier caso threads::create se queja correctamente si un nombre de subrutina no reconocido o no Cód.Ref se pasa en En su caso,.. sin embargo, está segfaulting demasiado rápido para llegar a este manejo de errores.)

  3. Las codificaciones no son seguras para hilos.
    De nuevo as documented in encodings, el módulo encoding no es seguro para subprocesos. Este es el código más pequeño posible que pudiera llegar a reproducir sus síntomas:

    use threads; 
    open my $OUTPUT , ">:encoding(utf8)", "/dev/null" or die $!; 
    threads->create(sub {})->join; 
    

    Eso es Perl 5.12.1 con hilos-1,77 en i686-linux-hilos múltiples, si está interesado. Suelta la magia "utf8", y funciona bien.

    Esta es su violación de segmento

+0

nice answer ... – masonk

+0

Esto me ahorró horas de búsqueda de la causa de mi segfault. ¡Gracias! –