Perl Thread Safe Modules
I am trying to take a Perl program I wrote and thread it. The problem is I read that some modules aren't "thread safe". How do I know if a module is thread safe? I've looked around for a list and cannot locate one.
To test out one module I use frequently (Text::CSV_XS) I tried the following code out:
use strict;
use warnings;
use threads;
use threads::shared;
require Text::CSV_XS;
my $CSV = Text::CSV_XS->new ({ binary =&开发者_如何学Pythongt; 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
The output I receive is the following:
Hello thread number: 1 Segmentation fault
Does this mean the module is not thread safe, or is it another problem?
Thanks
Generally speaking, core and high-visibility modules are thread-safe unless their documentation says otherwise.
That said, there are a few missteps in your post:
share($CSV)
This clears$CSV
(a blessed hashref), just as documented inthreads
. Generally, you want to share() complex objects prior to initialization or, perhaps in this case, share() some dumb$lock
variable between threads.
Since$CSV
holds state for the underlying XS, this might lead to undefined behavior.
But this isn't your segfault.threads->create(\&sayHello('1'));
You are mistakenly invokingsayHello(1)
in the main thread and passing a reference to its return value tothreads->create()
as a (bogus) start routine. You meant to say:threads->create(\&sayHello, '1');
But this isn't your segfault.
(EDIT Just to clarify -- a bad start routine here doesn't risk a SEGV in any case.
threads::create
properly complains if an unrecognized subroutine name or non-CODE ref is passed in. In your case, however, you are segfaulting too quickly to reach this error handling.)Encodings are not thread-safe.
Again as documented inencodings
, theencoding
module is not thread-safe. Here's the smallest possible code I could get to reproduce your symptoms:use threads; open my $OUTPUT , ">:encoding(utf8)", "/dev/null" or die $!; threads->create( sub {} )->join;
That's perl 5.12.1 with threads-1.77 on i686-linux-thread-multi, if you're interested. Drop the "utf8" magic, and it works just fine.
This is your segfault
精彩评论