2009-09-26 1 views
7

Какие модули следует искать для многопоточности в Perl?Какие модули следует использовать для многопоточности в Perl?

Я ищу что-то довольно низкое; Я хочу, чтобы потоки выполняли несколько рабочих одновременно, причем каждый из них спал в течение различного времени.

ответ

7

В последних версиях Perl имеется поддержка потоковой передачи. Запустите perl -V:usethreads, чтобы узнать, доступна ли она в вашей системе.

$ perl -V:usethreads 
usethreads='define' 

perldoc threads дает довольно хорошее введение в их использовании.

+2

Никогда не используйте ithreads для чего-либо. – jrockway

+0

Ссылка не работает –

7

Если производительность не является большой проблемой, то процесс обработки нескольких процессов, вероятно, будет намного проще, чем иметь дело с потоками. Я часто использую Parallel::ForkManager, который очень прост, но очень хорош в том, что он делает.

5

Похоже, вам не нужна превентивная многопоточность; в этом случае рассмотрим кооперативную модель POE. Поскольку ваш код будет доступен только для других потоков, когда вы решите, и у вас будет только один поток, работающий одновременно, разработка и отладка будут намного проще.

+3

Стоит отметить, что хотя POE не подразумевает поддержку многопоточности или многопроцессорности, 'POE :: Wheel :: Run' позволяет запускать часть кода в разветвленном процессе, переводя его состояние ввода-вывода и выхода в события POE. Иногда очень полезно обернуть блокирующий код. – hobbs

+0

Я второй, что _ – xxxxxxx

2

Coro - хороший модуль для совместной многозадачности.

99% времени, это то, что вам нужно, если вы хотите, чтобы потоки в Perl.

Если вы хотите, чтобы потоки ускоряли ваш код, когда несколько ядер доступны, вы идете по неправильному пути. Perl в 50 раз медленнее, чем другие языки. Перезапись кода для работы на двух процессорах означает, что теперь он работает только на 25 раз медленнее, чем на других языках ... на одном CPU. Лучше потратить усилия на перенос медленных частей на другой язык.

Но если вы просто не хотите, чтобы IO блокировал другие «потоки», тогда Coro именно то, что вы хотите.

+1

Существует также скорость разработки. –

+0

Я устал от этого аргумента :) Есть много вещей, которые я могу взломать как можно быстрее в Haskell, как в Perl, а Haskell работает намного быстрее, чем perl. – jrockway

+0

Я согласен с частями этого, но утверждая, что Perl на 50 раз медленнее, чем другие языки, является преувеличением, которое применяется только к определенным операциям. Как вы знаете, IO и регулярные выражения Perl находятся на одном уровне с лучшими скомпилированными языками. Если программист может определить узкие места и имеет время разработки, может быть стоит написать некоторый код в DSL, используя Inline :: C. Если им нужно переписать большую часть своего кода в DSL, чтобы получить хорошие ускорения производительности, то может иметь смысл полностью отказаться от Perl. –

9

Существует много причин, по которым вы, возможно, не захотите многопоточность. Однако, если вы хотите многопоточность, следующий код может служить полезным примером. Он создает несколько заданий, помещает их в потокобезопасную очередь, затем запускает некоторые потоки, которые вытягивают задания из очереди и завершают их. Каждый поток продолжает вытягивать задания из очереди в цикле, пока не увидит больше заданий. Программа ждет завершения всего потока и затем распечатает общее время, затрачиваемое на работу.

#!/usr/bin/perl 

use threads; 
use Thread::Queue; 
use Modern::Perl; 

my $queue= Thread::Queue->new; 
my $thread_count= 4; 
my $job_count= 10; 
my $start_time= time; 
my $max_job_time= 10; 

# Come up with some jobs and put them in a thread-safe queue. Each job 
# is a string with an id and a number of seconds to sleep. Jobs consist 
# of sleeping for the specified number of seconds. 
my @jobs= map {"$_," . (int(rand $max_job_time) + 1)} (1 .. $job_count); 
$queue->enqueue(@jobs); 

# List the jobs 
say "Jobs IDs: ", join(", ", map {(split /,/, $_)[0]} @jobs); 

# Start the threads 
my @threads= map {threads->create(sub {function($_)})} (1 .. $thread_count); 

# Wait for all the threads to complete their work 
$_->join for (@threads); 

# We're all done 
say "All done! Total time: ", time - $start_time; 

# Here's what each thread does. Each thread starts, then fetches jobs 
# from the job queue until there are no more jobs in the queue. Then, 
# the thread exists. 
sub function { 
    my $thread_id= shift; 
    my ($job, $job_id, $seconds); 
    while($job= $queue->dequeue_nb) { 
    ($job_id, $seconds)= split /,/, $job; 
    say "Thread $thread_id starting on job $job_id ", 
     "(job will take $seconds seconds)."; 
    sleep $seconds; 
    say "Thread $thread_id done with job $job_id."; 
    } 
    say "No more jobs for thread $thread_id; thread exiting."; 
} 
Смежные вопросы