Следующее, кажется, не работает в параллельных потоках, как я ожидал, а скорее каждый процесс блоки, пока это не завершено:
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
Как я выполняю параллельные потоки в жемчуге?
См. потоков perldoc
.
Проблема в том, что вызов join ()
в потоке ожидает его завершения. Вы хотите создавать потоки, а затем присоединяться к ним, а не создавать / присоединяться как одну операцию.
Дальнейший взгляд на потоки perldoc
говорит:
потоки-> список ()
потоки-> список (потоки :: все)
потоки-> список (потоки :: запущен)
потоки-> список (потоки :: joinable)
Без аргументов (или с использованием потоков :: все) и в контексте списка возвращает список всех несоединенных, неотделенных объекты потоков. В скалярном контексте возвращает количество таких же.
С истинным аргументом (с использованием thread :: running), возвращает список всех несоединенных, неотделенные объекты потоков, которые Все еще работает.
С аргументом false (с использованием thread :: joinable) возвращает список всех несоединенных, неотделенных объектов потоков, которые завершили работу (т. Е. Для которых -> join () не будет блокировать).
Вы можете использовать это для цикла и перечисления потоков, присоединяясь, когда это возможно, до тех пор, пока все потоки не будут завершены (и вам, вероятно, понадобится верхний предел времени ожидания, когда вы их убьете и прервете)
вы должны присоединиться к ним потом , а не во время их создания:
my @arr = (1,2,3,4);
my @threads;
foreach (@arr) {
push @threads, threads->new(\&doSomething, $_);
}
foreach (@threads) {
$_->join();
}
Вы должны вызвать join
после создания всех потоков:
perl -mthreads -le'$_->join for map threads->new(sub{print"Thread $_";sleep(2)}),1..4'
join
(не только в Perl) заставляет вызывающий поток ждать завершения другого потока. Итак, ваш пример порождает поток, ожидает его завершения, а затем порождает другой поток, поэтому у вас создается впечатление, что потоки не созданы вообще.