Как выполнить параллельные потоки в жемчуге?

Следующее, кажется, не работает в параллельных потоках, как я ожидал, а скорее каждый процесс блоки, пока это не завершено:

my @arr = (1,2,3,4);
foreach (@arr) {
   threads->new(\&doSomething, $_)->join;
}

sub doSomething {
    my $thread = shift;
    print "thread $thread\n";
    sleep(5);
}

Другими словами, это, кажется, выполняет то же, как нерезьбовая версия была бы:

my @arr = (1,2,3,4);
foreach (@arr) {
   doSomething($_);
}

Я выполняю ActivePerl v5.10.1 mswin32-x86-multi-thread

Как я выполняю параллельные потоки в жемчуге?

9
задан user210757 22 June 2010 в 16:07
поделиться

4 ответа

См. потоков perldoc .

Проблема в том, что вызов join () в потоке ожидает его завершения. Вы хотите создавать потоки, а затем присоединяться к ним, а не создавать / присоединяться как одну операцию.

Дальнейший взгляд на потоки perldoc говорит:

потоки-> список ()

потоки-> список (потоки :: все)

потоки-> список (потоки :: запущен)

потоки-> список (потоки :: joinable)

Без аргументов (или с использованием потоков :: все) и в контексте списка возвращает список всех несоединенных, неотделенных объекты потоков. В скалярном контексте возвращает количество таких же.

С истинным аргументом (с использованием thread :: running), возвращает список всех несоединенных, неотделенные объекты потоков, которые Все еще работает.

С аргументом false (с использованием thread :: joinable) возвращает список всех несоединенных, неотделенных объектов потоков, которые завершили работу (т. Е. Для которых -> join () не будет блокировать).

Вы можете использовать это для цикла и перечисления потоков, присоединяясь, когда это возможно, до тех пор, пока все потоки не будут завершены (и вам, вероятно, понадобится верхний предел времени ожидания, когда вы их убьете и прервете)

13
ответ дан 4 December 2019 в 06:55
поделиться

вы должны присоединиться к ним потом , а не во время их создания:

my @arr = (1,2,3,4);
my @threads;
foreach (@arr) {
   push @threads, threads->new(\&doSomething, $_);
}
foreach (@threads) {
   $_->join();
}
13
ответ дан 4 December 2019 в 06:55
поделиться

Вы должны вызвать join после создания всех потоков:

perl -mthreads -le'$_->join for map threads->new(sub{print"Thread $_";sleep(2)}),1..4'
1
ответ дан 4 December 2019 в 06:55
поделиться

join (не только в Perl) заставляет вызывающий поток ждать завершения другого потока. Итак, ваш пример порождает поток, ожидает его завершения, а затем порождает другой поток, поэтому у вас создается впечатление, что потоки не созданы вообще.

3
ответ дан 4 December 2019 в 06:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: