7

我有一个程序(Perl)启动大量线程(每个线程负责基于数据处理创建图形)。我开始使用的每个线程:

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;
        }
    }
}

所以每次我想创建一个新线程时,我都会调用

&checkThreads;

在我等待一些线程清理时,这会造成延迟。问题是,当我调用那个 sub 时,我点击了我检查的那一行:

$task->is_running()

程序退出并停止运行,没有任何错误或警告。我只想要一个计算正在运行的线程来限制它们的子程序。

如何成功执行此计数?

我尝试过的其他事情正在评估以下行:

scalar(threads->list());

但这给了我一个奇怪的价值,就像它是一个我认为看起来像这样的无福参考:

threads=SCALAR(0x80fea8c)
4

3 回答 3

6

Thread::Semaphore提供了一个计数信号量来限制并发:

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;
}
于 2012-07-22T01:55:32.060 回答
1

看文档,

my $count = threads->list();

应该工作,与你所说的相反。正在使用的线程版本的文档说什么?好吧,您可以使用以下方法作为解决方法。

my $count = () = threads->list();
于 2012-07-22T01:28:02.123 回答
0
man perlthrtut

What Threads Are Running?
   "threads->list()" returns a list of thread objects, one for each thread
    that's currently running and not detached.  Handy for a number of

换句话说,找出threads->list() 返回的列表中有多少项目,然后你就知道了。

您可能想调查Thread::Pool或其他 cpan 包,看看是否其他人已经为您完成了繁重的工作。

于 2012-07-22T00:50:46.950 回答