C 使用pthreads作为带有队列的线程池?

C 使用pthreads作为带有队列的线程池?,c,C,我对C很陌生,如果这个问题很离题,我很抱歉。我曾使用Java executor服务创建固定线程池,但在理解如何在C中执行类似操作时遇到了困难 我学习了如何使用pthreads在c中创建线程(这似乎很简单),但我不确定如何创建一个固定数量的线程使用的队列?到目前为止,我所做的所有教程要么自己在主语句中启动线程,要么在for循环中启动线程。如果我采用这种方法,那么当我只需要3个或4个线程时,我将拥有数百万个线程(每个工作项1个),并让它们处理一个队列 这可能吗?如果可能,我需要学习什么?如果pthr

我对C很陌生,如果这个问题很离题,我很抱歉。我曾使用Java executor服务创建固定线程池,但在理解如何在C中执行类似操作时遇到了困难

我学习了如何使用pthreads在c中创建线程(这似乎很简单),但我不确定如何创建一个固定数量的线程使用的队列?到目前为止,我所做的所有教程要么自己在主语句中启动线程,要么在for循环中启动线程。如果我采用这种方法,那么当我只需要3个或4个线程时,我将拥有数百万个线程(每个工作项1个),并让它们处理一个队列


这可能吗?如果可能,我需要学习什么?如果pthreads无法实现,那么我很乐意使用其他工具,我正在mac上开发并将其部署到linux上。

通过使用条件变量,您可以使用单生产者/多消费者模型轻松实现这一点。请记住,这是一种架构,其他架构当然是可能的

在主线程中,只需创建队列、互斥体和条件变量,然后启动任意数量的线程,伪代码如下:

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
完成所有工作项后,等待队列清空,然后发布一些sentinel项以关闭线程,然后等待它们完成,然后退出

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

这基本上允许您拥有固定数量的线程来处理队列上的项目,并且队列本身受互斥锁的保护,这样工作线程或主线程之间就不会发生争用。

您有什么特别的理由要这样做吗?现在创建和删除线程非常有效。除非你有一个关键的应用程序(很多线程几乎什么都不做),否则你应该专注于其他事情(正确性、活跃性、竞争…@JensGustedt我正在处理一个100GB的日志文件,每行大约需要500万次操作。我认为数据的输入速度将快于我处理它的速度,因此我希望有一个阻塞队列,并让线程使用它。B/C工作负载太重了,我想最好控制线程的数量(不是高效地创建/删除线程,而是B/C我的处理部分非常cpu密集)。我在这里做了很多假设(就像我在Java程序中做的那样),所以请纠正我所做的任何错误假设。你的问题描述听起来很复杂,如果你还没有足够的经验在C语言中正确处理问题,这已经是一个相当大的挑战。首先,尝试正确处理问题。然后,如果您发现性能不是您期望的,请进行测量。这是唯一知道的方法。很多时候,即使是有经验的程序员也不能正确估计程序的瓶颈所在。线程创建有时可能是一个瓶颈,但它肯定不是第一件要寻找的东西。@JensGustedt我知道我会在构建和测试方面遵循您的建议(我已经有了工作代码,但它不是线程化的)。我尝试这样做并不是为了优化线程方面,而是通过使用阻塞队列来控制流&让线程处理它。我正在阅读如何创建阻塞队列,但我不了解如何使线程保持活动状态以处理队列(我可以将它们置于无限循环中,但不确定这是否是一个好主意)。只是为了澄清我的意图。我先从你的方法开始。谢谢。标准方法是使用生产者-消费者模型。这可以通过使用互斥锁和条件变量在线程之间发送信号来实现。