Multithreading 如何限制perl中并行线程的最大数量
我有一个程序(Perl),可以启动大量线程(每个线程负责基于数据处理创建图形)。 我开始使用的每个线程:Multithreading 如何限制perl中并行线程的最大数量,multithreading,perl,Multithreading,Perl,我有一个程序(Perl),可以启动大量线程(每个线程负责基于数据处理创建图形)。 我开始使用的每个线程: my @threads //list to store threads that have been launched push @threads,threads->create(\mySubName,params...); 线程正常启动,但过了一段时间,在我打开其中几个线程后,Perl解释器崩溃(我认为它与内存有关?)。所以我的解决方案是限制每次打开的线程数,我选择了15个。我想
my @threads //list to store threads that have been launched
push @threads,threads->create(\mySubName,params...);
线程正常启动,但过了一段时间,在我打开其中几个线程后,Perl解释器崩溃(我认为它与内存有关?)。所以我的解决方案是限制每次打开的线程数,我选择了15个。我想在每个创建行之前添加一个子线程,以检查是否可以启动下一个线程或在等待一个线程完成时执行睡眠。我就是这样做的
sub checkThreads{
my $addThread = 0;
until($addThread){
my $totalThreads = 0;
foreach my $task (@threads){
if($task->is_running()){$totalThreads++;}
}
if($totalThreads <= 15 ){
print "Ok to add new thread, carry on!\n";
$addthread = 1;
}else{
print "Waiting for $totalThreads threads to fire next one...\n";
sleep 2;
}
}
}
在我等待一些线程清理时,这会造成延迟。
问题是,当我呼叫该潜艇时,当我到达检查线时:
$task->is_running()
程序退出并停止运行,没有任何错误或警告。我只想要一个统计运行线程数的子线程来限制它们
如何成功执行此计数
我尝试过的其他方法是评估以下行:
scalar(threads->list());
但这给了我一个奇怪的值,好像它是一个未删减的引用,我相信它看起来像:
threads=SCALAR(0x80fea8c)
换句话说,找出threads->list()返回的列表中有多少项,然后计算出您的计数
您可能需要调查或其他cpan包,看看是否有其他人已经为您完成了繁重的工作。查看文档
my $count = threads->list();
与你所说的相反,它应该起作用。您正在使用的线程版本的文档说明了什么?那么,您可以使用以下方法作为解决方法
my $count = () = threads->list();
提供限制并发性的方法:
my $sem = Thread::Semaphore->new(15); # max 15 threads
my @threads = map {
# request a thread slot, waiting if none are available:
$sem->down;
threads->create(\&mySubName, @params)
} 0..100;
$_->join for @threads;
在你的职能中:
sub mySubName {
do_stuff();
# release slot:
$sem->up;
}
顺便说一句,这是(字符串化)非常非常顺便说一句-请记住perl中的线程与其他编程语言中的线程不同-它们非常需要资源,因为每个线程都有所有变量的副本。它们在某些情况下仍然很有用,但在我必须进行并行化的每种情况下,分叉的效果都要好得多。这与你的问题没有直接关系,我只是想告诉你。:)什么版本的Perl?什么版本的线程?当我尝试使用threads->list()时,我得到以下结果:在@INC中找不到auto/threads/lists.al(@INC包含:C:\Program Files(x86)\ActiveState Komodo 3.5\lib\support\dbgp\perllib C:\Program Files(x86)\ActiveState Komodo 3.5\lib\support\dbgp\perllib C:/Perl/lib C:/Perl/site/lib。)在C:\path\main3.pl行508如果
threads->list()
返回一个列表,则可以比使用循环更容易地捕获长度……比如$totalThreads=scalar(threads->list())代码>,不是吗?好吧,这是一个输入错误,我用了threads->list()而不是threads->list(),但现在我运行这个$totalThreads;foreach my$thr(threads->list()){$totalThreads++;}打印“活动线程:”$全部线程。“\n”;我得到的是:在串联(.)中,对我print@jonathan,如果我使用scalar()方法,我会得到相同的消息:当我尝试打印count@Jonathan莱夫勒,不,要想知道列表的长度,你必须使用我用过的技巧。尽管如此,thread->list
假定返回标量上下文中的线程数。OP必须有一个旧版本的threads.pm.Richard我认为这是可行的,我在脚本中实现了它,看起来它确实在控制我的最大线程数,有没有一种方法可以窥视信号量持有的当前值?因为我运行了它,但在运行了一段时间后,我的脚本挂起在$sem->下代码>我将线程数量降低到了5个,它工作得很好,仍然有7个线程,看起来程序在某个时候会暂停,不知道为什么。谢谢你的提示!您可以通过取消对对象本身的引用来获得信号量的货币值,该对象本身只是对最大值(默认值为1)减去其计数的幸运引用。因此,要获得当前未完成的线程数,请计算$max-$$sem
。我们可以使用共享标量变量来计算正在运行的线程数吗?我的意思是在mySubName()的第一行,我们将计数器增加1,并在返回时将其减少1。我使用了Richard提出的信号量方法,但我尝试了这个方法,它确实给出了列表中实际线程的计数,谢谢!
my $sem = Thread::Semaphore->new(15); # max 15 threads
my @threads = map {
# request a thread slot, waiting if none are available:
$sem->down;
threads->create(\&mySubName, @params)
} 0..100;
$_->join for @threads;
sub mySubName {
do_stuff();
# release slot:
$sem->up;
}