我对C很新,很抱歉,如果这个问题很严重的话。我已经使用Java执行器服务来创建固定的线程池,并且无法理解如何在C中执行类似的操作。
我学会了如何使用pthreads在c中创建线程(这似乎很容易),但我不确定如何创建一个固定数量的线程消耗的队列?到目前为止,我所做的所有教程要么自己在主语句中启动线程,要么在for循环中执行。如果我采用这种方法,那么当我想要的只有3或4并让它们处理队列时,我将拥有数百万个线程(每个工作项1个)。
这是否可行,如果是,我需要学习什么?如果pthreads不可能,那么我很乐意使用其他东西,我正在使用mac进行开发并将其部署在linux上。
答案 0 :(得分:2)
使用条件变量可以合理地轻松地使用uniproducer / multiconsumer模型。请记住,这是一个架构,其他人当然是可能的。
在主线程中,您只需创建队列,互斥和条件变量,然后启动您想要运行的多个线程,伪代码如:
glbQueue = []
glbMutex = new mutex
glbCondVar = new condvar
for i = 1 to 10:
start thread using thrdFn
下一步是将所需的任何工作项添加到队列中(使用互斥锁)并踢出条件变量以根据需要唤醒线程:
while workitem = getNextWorkItem():
lock glbMutex
glbQueue.append (workItem)
kick glbCondVar
unlock glbMutex
完成所有工作项后,等待队列清空,然后发布一些标记项以关闭线程,然后等待它们完成,然后退出。
lock glbMutex
while glbQueue is not empty:
kick glbCondVar
unlock glbMutex.
sleep for a bit
lock glbMutex
unlock glbMutex.
for i = 1 to 10:
lock glbMutex
glbQueue.append (endWorkItem)
kick glbCondVar
unlock glbMutex.
wait for any one thread to exit
exit
完成工作的线程也相对简单。首先,它们在无限循环中运行,等待条件变量被踢。在该循环中,他们处理工作项直到不再可用,然后他们又回到睡眠状态。
一旦线程收到最终工作项,它就会退出,保证每个线程都有一个最终项。
换句话说,比如:
initialise
stillGoing = true
lock glbMutex
while stillGoing:
wait on glbCondVar using glbMutex
while stillGoing and glbQueue is not empty:
extract workItem from glbQueue to thread local storage
unlock glbMutex.
if workItem is endWorkItem:
stillGoing = false
else:
do the work specified by workItem
lock glbMutex
unlock glbMutex
clean up
exit thread
这基本上允许您在队列上有固定数量的线程处理项目,并且队列本身受到互斥锁的保护,因此工作线程或主线程之间不会发生争用。