有没有办法制作“工作线程”基本上我每次需要时都尝试创建线程,这导致比1线程慢,因为创建新线程总是很昂贵。是否有办法在应用程序首次启动时创建工作线程,然后在必要时让它们工作?
由于
答案 0 :(得分:7)
是的,您可以预先创建线程并让它们等待信号开始工作。
这些信号可以是消息队列或信号量或任何其他类型的线程间通信方法。
作为一个例子,我们曾经在UNIX下组建了一个系统,该系统有一个主线程,可以通过网络接收工作并将作业转移到从属线程。从属线程实际上必须通过屏幕抓取(基本上模拟用户)与另一个系统交互以获得他们想要的信息。
换句话说,工作可以比奴隶线程更快地完成。
所以我们启动了大约五十个奇怪的奴隶,并为他们创建了一个条件变量(这是使用pthreads)。没有做主动工作的每个奴隶只是等待条件变量。
当一个作业进入主线程时,它将相关数据加载到已知存储器中并“踢”条件变量,唤醒其中一个从器件,然后抓取工件并开始处理它(在通知主器件之后)它可以继续)。
因此,不必动态创建线程 - 所有这些都是在应用程序启动时创建的,只是等待工作交付。
当然,这种静态大小的潜在缺点是,如果你真的需要更多的线程,你可能会遇到麻烦。我们通过简单地监视线程的最大数量来解决这个问题,并确保在第二天重新启动进程,如果我们一直在用完,那就更多了。
如果您想要一个更动态的解决方案,您需要研究一个称为线程池的概念。这基本上就是我上面所描述的,但它通常允许您设置最小和最大线程数以及非活动线程在没有工作的情况下生存的最长时间(除非您已经处于最低限度)。
它的实现可能很简单:
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
(当然,如果您决定在线程启动后更改它们,那么当然,numslaves
,freeslaves
,slavequeue
以及其他共享变量的信号量保护正确。
并且,如果您的环境已经有线程池,我建议您使用它而不是尝试转换上面的伪代码。我的代码来自内存,旨在说明一点 - 它可能是也可能不是无错误的: - )
答案 1 :(得分:0)
这通常通过创建消息队列来完成。一个线程会等待某个对象,其中的信号将表明有新的工作需要完成。
答案 2 :(得分:0)
在win32上有一个非常好的线程池 - esp vista和Windows 7以上版本。我总是发现,考虑需要同时执行的任务而不是考虑单个线程,这是有用的。
此外,Visual C ++ 2010附带的并行模式库(我认为它被称为ConcRT)看起来非常强大(并且具有简单的接口)。我自己还没有用过它。 MSDN链接是 - http://msdn.microsoft.com/en-us/library/dd492418.aspx