Perl线程安全模块

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

一般来说,核心和高可见性模块线程安全的,除非他们的文档另有说明.

也就是说,你的帖子中有一些错误:

  1. share($CSV)
    这清除$CSV(一个祝福的hashref),就像在文档中记录的那样threads.通常,您希望初始化之前共享()复杂对象,或者在这种情况下,$lock在线程之间共享()一些哑变量.
    由于$CSV保留了底层XS的状态,因此可能会导致未定义的行为.

    但这不是你的段错误.

  2. threads->create(\&sayHello('1'));
    你错误地调用sayHello(1)在主线程和通过它的返回值的引用threads->create()作为一个(假的)启动程序.你的意思是说:

    threads->create(\&sayHello, '1');
    
    Run Code Online (Sandbox Code Playgroud)

    但这不是你的段错误.

    (编辑只是为了澄清 - 这里的一个糟糕的启动例程在任何情况下都不会冒SEGV的风险. threads::create如果传入一个无法识别的子例程名称或非CODE引用,则会适当地抱怨.但是,在你的情况下,你很快就会陷入困境.达到此错误处理.)

  3. 编码不是线程安全的.
    再次如文档所述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"魔法,它工作得很好.

    这是你的段错误