Потоки Perl будут использовать преимущества нескольких ядер и процессоров. Основным преимуществом потоков является то, что они довольно легко обмениваются данными между потоками и координируют их действия. Разветвленный процесс не может легко возвращать данные родителю или координировать между собой.
Основные минусы потоков Perl в том, что они относительно дороги в создании по сравнению с форком, они должны копировать всю программу и все ее данные; вы должны собрать их в свой Perl; и они могут быть глючными, чем старше Perl, тем более жгучие потоки. Если ваша работа дорогая, время создания не должно иметь значения.
Вот пример того, как вы можете сделать это с потоками. Есть много способов сделать это, этот использует Thread :: Queue , чтобы создать большой список работ, которые ваши рабочие потоки могут разделить. Когда очередь пуста, потоки выходят. Основным преимуществом является то, что легче контролировать, сколько потоков активно, и вам не нужно создавать новый, дорогой поток для каждого бита работы.
Этот пример помещает всю работу в очередь за раз, но нет никаких причин, по которым вы не можете добавлять в очередь по ходу работы. Если бы вы сделали это, вы бы использовали dequeue
вместо dequeue_nb
, который будет ждать большего ввода.
use strict;
use warnings;
use threads;
use Thread::Queue;
# Dummy work routine
sub start_XFOIL_instance {
my $arg = shift;
print "$arg\n";
sleep 1;
}
# Read in dummy data
my @xfoil_args = <DATA>;
chomp @xfoil_args;
# Create a queue to push work onto and the threads to pull work from
# Populate it with all the data up front so threads can finish when
# the queue is exhausted. Makes things simpler.
# See https://rt.cpan.org/Ticket/Display.html?id=79733
my $queue = Thread::Queue->new(@xfoil_args);
# Create a bunch of threads to do the work
my @threads;
for(1..4) {
push @threads, threads->create( sub {
# Pull work from the queue, don't wait if its empty
while( my $xfoil_args = $queue->dequeue_nb ) {
# Do the work
start_XFOIL_instance($xfoil_args);
}
# Yell when the thread is done
print "Queue empty\n";
});
}
# Wait for threads to finish
$_->join for @threads;
__DATA__
blah
foo
bar
baz
biff
whatever
up
down
left
right