Perl Thread Safe Модули - PullRequest
       7

Perl Thread Safe Модули

9 голосов
/ 20 июля 2010

Я пытаюсь взять написанную мной программу на 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

Вывод, который я получаю, следующий:

Hello thread number: 1
Segmentation fault

Означает ли это, что модуль не является потокобезопасным, или это другая проблема?

Спасибо

1 Ответ

32 голосов
/ 20 июля 2010

Вообще говоря, модули ядра и высокой видимости являются поточно-ориентированными, если в их документации не указано иное.

Тем не менее, в вашем посте есть несколько ошибок:1006 *

share($CSV)Это очищает $CSV (благословенный хэшреф), так же, как описано в threads.Как правило, вы хотите совместно использовать () сложные объекты до до инициализации или, возможно, в этом случае, совместно использовать () некоторую немую переменную $lock между потоками.Поскольку $CSV содержит состояние для базового XS, это может привести к неопределенному поведению. Но это не ваша ошибка.

threads->create(\&sayHello('1'));Вы ошибочно вызываете sayHello(1) в главном потоке и передаете ссылку на его возвращаемое значение на threads->create() в качестве (поддельной) процедуры запуска.Вы хотели сказать:

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

Но это не ваша ошибка.

( РЕДАКТИРОВАТЬ Просто уточнить - плохое началоподпрограмма здесь не рискует SEGV в любом случае. threads::create правильно жалуется, если передано нераспознанное имя подпрограммы или ссылка не-CODE. В вашем случае, однако, вы слишком быстро сегрегируете, чтобы достичь этой обработки ошибок.)

Кодировки не являются поточно-ориентированными.Снова , как описано в encodings, модуль encoding не является поточно-ориентированным.Вот наименьший возможный код, который я мог бы воспроизвести для ваших симптомов:

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

Это perl 5.12.1 с threads-1.77 на i686-linux-thread-multi, если вам интересно.Отбросьте магию «utf8», и она отлично работает.

Это ваша ошибка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...