2010-07-20 70 views
9

我正在嘗試編寫一個Perl程序並將其寫入線程。問題是我讀過一些模塊不是「線程安全」的。我怎麼知道一個模塊是否線程安全?我查了一下列表,找不到一個。Perl線程安全模塊

爲了測試一個模塊,我經常使用(文字:: 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 

我收到的輸出如下:

 
Hello thread number: 1 
Segmentation fault 

這是否意味着該模塊不是線程安全的,還是另一個問題?

感謝

+1

嘗試拿出可以引起分段錯誤最小的方案。 – mob 2010-07-20 04:47:21

回答

32

一般來說,核心和高能見度的模塊線程安全的,除非他們的文檔,否則說。

這就是說,有在您的文章的幾個失誤:

  1. share($CSV)
    這將清除$CSV(有福hashref),just as documented in threads。通常,要共享()複製對象之前的以進行初始化,或者在這種情況下可能會在線程之間共享()一些啞變量$lock變量。
    由於$CSV爲底層XS保存狀態,因此可能會導致未定義的行爲。

    但這不是你的段錯誤。

  2. threads->create(\&sayHello('1'));
    您錯誤地在主線程中調用sayHello(1)並通過參考,它的返回值threads->create()的(假的)啓動程序。 你的意思是說:

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

    但是,這是不是你的段錯誤。

    編輯只是爲了澄清 - 在這裏一個糟糕的開局例程不無論如何風險SEGV threads::create如果無法識別的子程序名稱或不CODE裁判在傳遞正確抱怨你的情況,。但是,您很快就會發生錯誤,無法達到此錯誤處理。)

  3. 編碼不是線程安全的。
    再次as documented in encodingsencoding模塊不是線程安全的。 這裏是最小的代碼,我能得到重現你的症狀:

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

    這就是Perl的5.12.1與線程-1.77在i686-linux的線程多,如果你有興趣。放下「utf8」的魔法,它工作得很好。

    這是你的內存設計缺陷

+0

很好的答案... – masonk 2010-07-20 13:37:35

+0

這節省了我幾個小時的搜索我的段錯誤的原因。謝謝! – 2011-04-18 19:26:54