我正在尝试使用C ++ 11标准库中的多线程功能,并设想了以下情况。
我有一个维护线程队列的父类。如下所示:
std::queue<MyMTObject *> _my_threads;
班级MyMTObject
包含std::thread
个对象。
队列的固定大小为5,类最初从队列已满开始。
由于我有要处理的作业,我启动线程并将其从队列中删除。我想要的是在作业完成时获得通知以及指向MyMTObject
的指针,以便我可以将它们重新插入队列并使它们再次可用。
我基本上有两个问题:
1:这是个好主意吗?我知道我没有详细说明具体细节,但从广义上讲。当然,我将使用互斥锁控制对队列的所有访问。
2:有没有办法在不使用Qt
或boost
等外部库的情况下实施此通知机制。
对于重复项,我确实在网站上查找但找不到任何适合管理线程集合的内容。
答案 0 :(得分:2)
我不确定是否需要提及此问题,但std::thread
个对象无法重复使用。通常,保留std::thread
引用的唯一原因是std::thread::join
线程。如果您以后不打算加入该帖子(例如发送给线程并等待完成),通常会建议std::thread::detach
。
如果您正在尝试为线程池保留线程,则可能更容易让std::queue
上的每个线程阻塞并从队列中拉出对象来处理。使用std::mutex
和std::condition_variable
相对容易实现。它通常可以提供良好的吞吐量,但是为了更好地控制调度,您可以执行诸如为每个线程保持单独std::queue
之类的事情。
分离线程并创建工作队列还有一个额外的好处,即它可以避免冗余请求操作系统创建新线程,从而增加开销并增加整体资源使用。
答案 1 :(得分:1)
我认为您可以尝试部署某些版本的Reactor pattern。因此,您可以在这些工作人员之后启动一个清理的其他控制线程。现在,您创建一个ThreadSafeQueue
,用于将工作线程中的事件传递给控制线程。这个队列应该以这样一种方式实现,你可以在其上select
并等待另一端的任何活动(某些线程终止并调用queue.push
)。
总而言之,我认为这是一个非常优雅的解决方案。我确实增加了一个额外线程的开销,但是这个线程大部分时间都在休眠,只能在工作之后清理一次醒来。
答案 2 :(得分:0)
在Posix中没有优雅的方法可以做到这一点,C ++线程模型几乎是Posix的一个薄包装。
你可以加入一个特定的线程(一次一个),或者你可以等待期货 - 再次,一次一个未来。
你可以做的最好的事情是避免循环是使用一个条件变量,并在它们即将到来之前使所有线程在其上显示(以及指示哪一个刚刚通过设置某种每线程标志退出)出口。收割者&#39;会注意到信号并检查标志。
问题在于此解决方案需要线程协作。但我知道没有更好的。