在Perl中进行多线程处理时应该看哪些模块?
我希望做一些相当低的性能;我希望线程是同时运行多个工作者,每个工作人员都会在不同的时间内休眠。
答案 0 :(得分: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.";
}
答案 1 :(得分:7)
如果性能不是一个大问题,那么fork
多个进程可能比处理线程容易得多。我经常使用Parallel::ForkManager这很简单,但非常擅长它。
答案 2 :(得分:7)
最新版本的Perl具有线程支持。运行perl -V:usethreads
以查看它是否在您的系统中可用。
$ perl -V:usethreads
usethreads='define'
perldoc threads
为使用它们提供了很好的介绍。
答案 3 :(得分:5)
听起来你不需要先发制人的多线程;在这种情况下,请查看POE的合作模型。由于您的代码在您决定时只会产生其他线程,并且您一次只能运行一个线程,因此开发和调试将更加容易。
答案 4 :(得分:2)
Coro是一个很好的合作多任务模块。
99%的时间,如果您想在Perl中使用线程,这就是您所需要的。
如果您希望线程在多个核心可用时加速您的代码,那么您将走错路。 Perl比其他语言慢50倍。重写代码以在两个CPU上运行意味着它现在仅比一个CPU上的其他语言运行慢25倍。最好花费精力将缓慢的部分移植到另一种语言。
但如果你不想让IO阻止其他“线程”,那么Coro正是你想要的。