use*_*049 9 perl multithreading module
我正在尝试采用我编写的Perl程序并对其进行处理.问题是我读到一些模块不是"线程安全的".我如何知道模块是否是线程安全的?我环顾四周找不到一个清单.
为了测试我经常使用的一个模块(Text :: CSV_XS),我尝试了以下代码:
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
Run Code Online (Sandbox Code Playgroud)
我收到的输出如下:
Hello thread number: 1 Segmentation fault
这是否意味着模块不是线程安全的,还是另一个问题?
谢谢
pil*_*row 32
一般来说,核心和高可见性模块是线程安全的,除非他们的文档另有说明.
也就是说,你的帖子中有一些错误:
share($CSV)
这清除$CSV(一个祝福的hashref),就像在文档中记录的那样threads.通常,您希望在初始化之前共享()复杂对象,或者在这种情况下,$lock在线程之间共享()一些哑变量.
由于$CSV保留了底层XS的状态,因此可能会导致未定义的行为.
但这不是你的段错误.
threads->create(\&sayHello('1'));
你错误地调用sayHello(1)在主线程和通过它的返回值的引用来threads->create()作为一个(假的)启动程序.你的意思是说:
threads->create(\&sayHello, '1');
Run Code Online (Sandbox Code Playgroud)
但这不是你的段错误.
(编辑只是为了澄清 - 这里的一个糟糕的启动例程在任何情况下都不会冒SEGV的风险. threads::create如果传入一个无法识别的子例程名称或非CODE引用,则会适当地抱怨.但是,在你的情况下,你很快就会陷入困境.达到此错误处理.)
编码不是线程安全的.
再次如文档所述encodings,该encoding模块不是线程安全的.这是我可以重现症状的最小代码:
use threads;
open my $OUTPUT , ">:encoding(utf8)", "/dev/null" or die $!;
threads->create( sub {} )->join;
Run Code Online (Sandbox Code Playgroud)
如果你感兴趣的话,这是i686-linux-thread-multi上的线程为1.77的perl 5.12.1.删除"utf8"魔法,它工作得很好.
这是你的段错误