2010-07-07 43 views
3

有没有办法让“工作者线程”基本上我每次都需要创建线程,这导致比使用1线程慢,因为创建新线程一直都很昂贵。当应用程序第一次启动时,是否有办法创建工作线程,然后在必要时给它们工作?制作工作线程?

谢谢

+0

哪个平台?你怎么创建线程? – Naveen 2010-07-07 04:31:14

+1

你使用C还是C++?他们不是同一种语言。 – 2010-07-07 05:13:56

回答

7

是的,你可以预先创建线程,让他们等待信号去开始工作。

这些信号可以是消息队列或信号量或任何其它种类的线程间通信的方法的。

举个例子,我们曾经一起放在UNIX下一个系统,它有一个主线程接收过网和农场作业的工作出从属线程。从属线程实际上必须通过屏幕抓取(基本模仿用户)与另一个系统交互以获得他们所需的信息。

换句话说,工作可能比奴隶线程能做得更快。

于是我们开始了五十余奴隶,只是创造了他们一个条件变量(这是使用并行线程)。每个从事积极工作的奴隶只是等待条件变量。

当一个作业进入主线程时,它将相关数据加载到已知的内存中,并“踢”了条件变量,唤醒其中一个从站,然后抓取工作并开始处理它(在通知掌握它可以继续)。

所以没有开销不必动态创建线程 - 所有人都在应用程序启动时创建的,只是等待工作移交。

当然,有一个潜在的缺点,以这种静态的大小的,你可能会遇到麻烦,如果你确实需要更多的线程。我们通过简单地监视线程的最大数量来解决这个问题,并确保在第二天重新启动进程,如果我们一直耗尽的话,会更多。


如果你想有一个更动态的解决方案,你需要研究一个叫做线程池的概念。这基本上是我在上面描述的,但它通常允许您设置线程的最小和最大数量以及最大时间,一个非活动线程将被允许在没有工作的情况下生存(除非您已经处于最低限度)。

它的实现可以像这样简单的事情:

master: 
    minslaves = 7 
    maxslaves = 20 
    maxtime = 600 
    numslaves = 0 
    freeslaves = 0 

    while running: 
     while numslaves < minslaves: 
      increment numslaves and freeslaves 
      start a slave 
     endwhile 
     wait for work 
     if freeslaves = 0 and numslaves < maxslaves: 
      start a slave 
     endif 
     queue work to slavequeue 
    endwhile 
    while numslaves > 0: 
     wait 
    endwhile 
    exit 

和:

slave: 
    while running: 
     get work from slavequeue with timeout 
     if timed out: 
      if time since last work > maxtime and numslaves > minslaves: 
       break out of while loop 
      endif 
      restart while loop 
     endif 
     decrement freeslaves 
     do the work 
     increment freeslaves 
    endwhile 
    decrement numslaves and freeslaves 
    exit 

(当然,numslavesfreeslavesslavequeue的所有共享变量的正确信号保护和其他人,如果你决定在线程启动后改变它们)。

而且,如果你的环境已经有了线程池,我建议你使用它,而不是试图转换我上面的伪代码。我的代码来自内存,意在说明一点 - 它可能是也可能不是无bug的:-)

0

这通常通过创建消息队列来完成。一个线程会等待某个对象,其中的信号表明有新的工作要完成。

+0

另外:线程不是一种提高性能的方法,除非你正在做一些高度计算和受CPU限制的东西。 – 2010-07-07 04:32:01

+0

线程也可以提高I/O绑定应用程序的性能,只要(例如)您正在从一台设备读取数据并写入另一台设备。 – 2010-07-07 04:46:25

+0

@Jerry,分离读写不是I/O绑定应用的关键,每个线程使用不同的设备。 – 2010-07-07 08:25:25

0

在win32上有一个很好的threadpool - esp vista和windows 7以上版本。我一直认为从需要同时执行的任务角度思考比思考单个线程更有用。另外,Visual C++ 2010附带的并行模式库(我认为它被称为ConcRT)看起来非常强大(并且具有简单的接口)。尽管如此,我还没有用过它。 MSDN的链接是 - http://msdn.microsoft.com/en-us/library/dd492418.aspx