2010-07-20 30 views
9

Tôi đang cố gắng để có một chương trình Perl tôi đã viết và thread nó. Vấn đề là tôi đọc rằng một số mô-đun không phải là "thread an toàn". Làm cách nào để biết liệu mô-đun có phải là chủ đề an toàn không? Tôi đã xem xét một danh sách và không thể xác định được danh sách.Perl Chủ đề Mô-đun an toàn

Để kiểm tra ra một mô-đun tôi sử dụng thường xuyên (Text :: CSV_XS) Tôi đã thử các mã sau ra:

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 

Kết quả tôi nhận được là như sau:

 
Hello thread number: 1 
Segmentation fault 

Liệu này có nghĩa là các mô-đun không phải là chủ đề an toàn, hoặc nó là một vấn đề khác?

Cảm ơn

+1

Cố gắng đưa ra những chương trình nhỏ nhất bạn có thể là nguyên nhân gây lỗi segmentation. – mob

Trả lời

32

Nói chung, cốt lõi và tầm nhìn cao module thread-safe trừ khi tài liệu của họ nói ngược lại.

Điều đó nói rằng, có một vài sai lầm trong bài viết của bạn:

  1. share($CSV)
    này xóa $CSV (một hashref may mắn), just as documented in threads. Nói chung, bạn muốn chia sẻ() các đối tượng phức tạp trước để khởi tạo hoặc, có thể trong trường hợp này, hãy chia sẻ() một số biến số giữa các chủ đề là $lock.
    $CSV giữ trạng thái cho các XS cơ bản, điều này có thể dẫn đến hành vi không xác định.

    Nhưng đây không phải là segfault của bạn.

  2. threads->create(\&sayHello('1'));
    Bạn đang nhầm lẫn gọi sayHello(1) trong thread chính và đi qua một tham chiếu đến giá trị trả về của nó-threads->create() như một (giả) bắt đầu thói quen. Bạn có nghĩa là để nói:

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

    Nhưng đây không phải là segfault của bạn.

    (EDIT Chỉ cần làm rõ - một sự khởi đầu thói quen xấu ở đây không có nguy cơ một SEGV trong mọi trường hợp threads::create đúng phàn nàn nếu một tên chương trình con không được công nhận hoặc không MÃ ref được thông qua năm Trong trường hợp của bạn,.. tuy nhiên, bạn đang segfaulting quá nhanh để đạt được xử lý lỗi này.)

  3. Mã hóa không an toàn chỉ.
    Một lần nữa as documented in encodings, mô-đun encoding không an toàn chỉ. Dưới đây là các mã nhỏ nhất có thể tôi có thể nhận được để tái tạo các triệu chứng của bạn:

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

    Đó là perl 5.12.1 với đề-1.77 trên i686-linux-thread-đa, nếu bạn quan tâm. Thả "utf8" ma thuật, và nó hoạt động tốt.

    Đây là segfault bạn

+0

câu trả lời hay ... – masonk

+0

Điều này đã tiết kiệm cho tôi số giờ tìm kiếm nguyên nhân của sự phân đoạn của tôi. Cảm ơn! –