我有简单的 Perl 脚本,其中有一个大循环,在其中我调用或多或少的百万次函数my_fun()
。我想创建将处理它的线程池 - 同时最多 5 个线程将循环调用此方法。
使用最快的库对我来说真的很重要——看到例子真的很高兴。
我的代码如下所示:
for (my $i = 0; $i < 1000000 ; $i++) {
my_fun();
}
先感谢您
我有简单的 Perl 脚本,其中有一个大循环,在其中我调用或多或少的百万次函数my_fun()
。我想创建将处理它的线程池 - 同时最多 5 个线程将循环调用此方法。
使用最快的库对我来说真的很重要——看到例子真的很高兴。
我的代码如下所示:
for (my $i = 0; $i < 1000000 ; $i++) {
my_fun();
}
先感谢您
看看Parallel::ForkManager。它使用的是fork
,而不是线程,但它应该可以非常简单地完成您的工作。
示例从文档中提取并略有改动:
use Parallel::ForkManager;
my $pm = Parallel::ForkManager->new(5); # number of parallel processes
for my $i (0 .. 999999) {
# Forks and returns the pid for the child:
my $pid = $pm->start and next;
#... do some work with $data in the child process ...
my_fun();
$pm->finish; # Terminates the child process
}
$pm->wait_all_children;
我们不能给你最快的方法,因为这取决于工作,你没有告诉我们工作是什么。
但是您确实询问了线程,所以我将为您介绍线程应用程序的基础。这是一个工人模型。它是健壮的、可维护的和可扩展的。
use threads;
use Thread::Queue qw( ); # Version 3.01+ required
my $NUM_WORKERS = 5;
sub worker {
my ($job) = @_;
...
}
my $q = Thread::Queue->new();
my @workers;
for (1..$NUM_WORKERS) {
push @workers, async {
while (defined(my $job = $q->dequeue())) {
worker($job);
}
};
}
$q->enqueue($_) for @jobs; # Send work
$q->end(); # Tell workers they're done.
$_->join() for @workers; # Wait for the workers to finish.
这是一个基本流程(单向),但通过添加响应队列很容易实现双向。
这使用实际线程,但您可以通过切换use threads;
到use forks;
.
Parallel::ForkManager也可用于提供工作模型,但它不断创建新进程而不是重用它们。不过,这确实使它可以轻松处理儿童死亡。
查看线程文档。