Боюсь, я не собираюсь переписывать ваш код для вас, но я могу дать вам несколько советов о том, как выполнить многопоточность.
Что нужно понять о потоках perl, так это , а не легкая нить. Вы должны создать количество потоков, равное параллелизму, запустить их с Thread::Queue
и идти оттуда.
Вам также нужно избегать любых не поточно-безопасных модулей - вы можете использовать их, если вы осторожны , но это обычно означает создание их экземпляров в потоке с помощью require
и import
вместо use
в начале программы.
Я бы также предложил избегать попыток выполнять ваш выводной ввод-вывод параллельно - возвращать результаты потока и объединять их (сортировать, если необходимо) в «главном» потоке (или выделять отдельную программу записи).
Так что я бы пошел с чем-то вроде;
#!/usr/bin/env perl
use strict;
use warnings;
use threads;
use Thread::Queue;
use Storable qw ( freeze thaw );
my $NUM_THREADS = 16; #approx number of cores.
my $translate_q = Thread::Queue->new;
my $translate_results_q = Thread::Queue->new;
sub translate_thread {
while ( my $item = translate_q->dequeue ) {
my $seq = thaw $item;
my $pseq = $seq->translate();
$translate_results_q->enqueue( freeze $pseq );
}
}
threads->create( \&translate_thread ) for 1 .. $NUM_THREADS;
while ( my $seq => $seqin->next_seq ) {
$translate_q->enqueue( freeze($seq) );
}
$translate_q->end;
$_->join for threads->list;
$translate_results_q->end;
while ( my $result = $translate_results_q->dequeue ) {
my $pseg = thaw($result);
}
Примечание - это не будет работать как есть, потому что отсутствует слияние с остальной частью вашего ocde. Но, надеюсь, это иллюстрирует, как очереди и потоки могут работать, чтобы получить параллелизм?
Вы передаете свои объекты, используя freeze
и thaw
из Storable, и используете распараллеливание для их распаковки.
Не сходите с ума по количеству потоков - для преимущественно вычислительных рабочих нагрузок (например, без ввода-вывода) тогда число потоков, равное количеству ядер, является правильным. Если они будут блокировать ввод-вывод, вы можете увеличить это число, но обход двойного не очень поможет.
Вы не можете эффективно распараллелить дисковый ввод-вывод - просто так не работает. Так что сделайте это в «основной» теме.