线程占用大量CPU

时间:2011-03-06 02:23:16

标签: multithreading perl

我正在使用Thread帮助在perl中执行线程;我会说我对线程很新。

我的程序中有一个名为“max threads”的变量。如果线程数低于此数,则会提示新的线程数。我正在使用while循环来比较当前现有线程数与最大线程数变量。

我假设while循环是消耗我的cpu的东西。

无论如何,我可以让'boss'或'manager'线程(核心线程)在安排和管理线程时不占用尽可能多的cpu?如果我的CPU因为管理器线程而提升,那么最终根本就没有线程了!

3 个答案:

答案 0 :(得分:3)

如果你想保留当前的模型,你应该有一些信号(可能是一个信号量),当有太多的工人时,线程启动器可以阻止它。

一个更简单的模型是拥有一个工作池,并通过Thread :: Queue让它们工作。

my $q = Thread::Queue->new();

my @workers;
for (1..$MAX_WORKERS) {
    push @workers, async {
       while (my $job = $q->dequeue()) {
           ...
       }
    };
}

for (...) {
    $q->enqueue(...);
}

# Time to exit
$q->enqueue(undef) for 0..$#workers;

# Wait for workers to finish.
$_->join() for @workers;

答案 1 :(得分:2)

我不使用Perl,但从一般的异步编程角度来讲,你想要一个不会堵塞主线程的线程池管理器,这可以通过多种方式实现。首先,你可以使用一个线程(yay!)来做这样的事情(伪代码):

while program not terminating:
   wait a quarter-second or so, then
      do your "are-there-enough-threads" check

操作系统或抽象的运行时库通常会提供某种等待函数来暂停线程,直到经过一段特定的时间(因此在此期间不占用调度程序资源)。

或者,如果您的程序是事件驱动的(如在GUI环境中),您可以通过发布自己的计时器消息(主要由操作系统提供的另一项服务)在主线程上执行类似的池管理。

答案 2 :(得分:1)

与其他语言相比,Perl线程重量级。他们需要很多的资源才能开始;尝试在前面启动你需要的所有线程,并让它们继续运行。每次执行异步任务时启动新线程的效率都非常低。