【发布时间】:2017-10-31 08:29:23
【问题描述】:
目标是实现在单独的线程中执行任务的 Worker。问题在于正确设计 Worker 关闭路径。所以:
class Worker
{
/* ... */
/**
* @brief Thread pool worker constructor
*
* Runs the worker's taskRunner() in the stand alone thread.
*/
Worker( ThreadPool * threadPool )
{
/* Run the task runner in new thread */
this->mThread = std::thread( std::bind( & Worker::taskRunner, this, threadPool ) );
}
/* ... */
};
worker 在独立线程中运行它的成员方法Worker::taskRunner。 taskRunner 看起来像这样(删除了不必要的东西):
void taskRunner( ThreadPool * threadPool )
{
/* Infinite loop */
while( this->getState() != State::TERMINATED )
{
/* ... */
}
/* At this point, the thread is going to be finished */
}
一旦 taskRunner 的无限循环退出,我想删除 Worker 本身,该实例保存在 std::list 集合中的 ThreadPool 类中:
std::list<std::shared_ptr<Worker>> mWorkers;
我想使用void std::list::remove( const T& value ); 方法。
问题在于这个remove()是在哪个作用域调用的。
- 如果我在
taskRunner()方法的末尾调用它,它将 在Worker的线程范围内执行,对吧?但是是不是 从其成员中删除父对象的正确方法 线? - 我也想过用
boost::signals2::signal通知工作对象本身它的线程已完成,因此 工人可以要求线程池删除自己...?不是 矫枉过正?在主要之间发出信号会是一个有意义的解决方案吗 和工作线程?
一般来说,我想避免在主线程(Worker 正在运行的地方)中出现任何阻塞模式...... 非常感谢任何人知道如何解决这个问题......
【问题讨论】:
-
通常您会将任务传递给线程池类,该类管理任务队列,将任务分配给不同的工作人员,并在一切完成后进行清理。工人被生成一次并等待新任务的到来。线程池的重点是不必为每个新任务生成一个新线程,这可能非常昂贵。如果您为每个任务生成一个新线程,为什么还要有一个
Worker类? -
@cantordust 你是对的。线程池应管理从队列中获取任务的有限数量的工作人员。这就是线程池的原理。但是,如果任务在某种程度上依赖于等待——一项任务可能会等待另一项也被阻止或什至没有安排的任务。在这种情况下,解决方案是临时添加另一个执行此工作的工人。一旦情况发生变化,工人的数量就会再次受到限制。长话短说,线程池应保持定义数量的活动工作线程,而不是保持恒定数量的可能等待线程。
-
我明白了。只是一个建议:如果某些任务需要等待其他任务完成,也许您可以使用优先级队列(可能是
std::priority_queue<std::shared_ptr<Worker>>?)。在Worker类中定义优先级,并为队列提供一个自定义比较器,以首先调度具有最高优先级的工作人员。然后,当您一次弹出一个任务时,您将按优先级顺序处理任务,您可以在完成后立即丢弃工作人员。 -
@cantordust 哦,好主意!但是
std::priority_queue应该用于任务队列,不是吗?工人只是被保存在某个容器中(std::list),它允许从列表中的任何位置插入和删除恒定时间元素(这是我的选择标准) -
std::list具有恒定的时间插入和删除元素,但前提是您已经有一个指向正确元素的迭代器。否则,您将不得不将列表遍历到正确的位置,这平均是线性时间。我建议std::unordered_map,因为它具有恒定时间插入、擦除和查找功能。关于priority_queue,我在考虑std::priority_queue<std::shared_ptr<Worker>>,甚至只是std::priority_queue<Worker>。Worker可以有一个数据成员int priority,一个std::thread持有任务,operator ()执行任务。
标签: c++ multithreading c++11 c++14 worker