【问题标题】:Managing multiple concurrent threads管理多个并发线程
【发布时间】:2012-07-02 19:02:54
【问题描述】:

我正在使用 C++11 线程库在 C++ 中编写一个多线程程序。

我有以下要求:

  1. 主线程监听某种类型的事件,并为每个新事件触发一个新线程
  2. 当请求程序终止时,新线程创建被阻止,我们等待旧线程完成

我可以选择将线程存储在某个容器中,例如列表。在退出之前,容器中的所有线程都是join()-ed。但是,由于 STL 容器不是线程安全的,因此在添加新线程和从容器中删除完成的线程时需要额外的同步。在这种情况下,主线程和子线程之间的交互变得有点复杂。子线程是否应该将自己从容器中移除?如果不是,它如何让主线程知道何时删除?等等

我看到的另一种方法是拥有一个原子 int,它在创建子线程时由主线程递增,并在子线程终止之前由子线程递减(创建后线程将是 detach()-ed,所以我不必管理任何 std::thread 对象)。在退出之前,我们只需在一个简单的循环中等待原子整数变为 0。这个解决方案对我来说看起来更好,因为移动部件更少并且没有锁定(至少只要目标平台具有std::atomic<int> 的无锁实现)。

那么,我的问题是,您更喜欢上述哪种方法?

【问题讨论】:

  • 每个活动都需要一个新线程吗?如果你有很多东西,特别是如果它们很短,线程创建/销毁将是一个巨大的开销。根据您的情况,您可能希望使用固定数量的工作线程来实现某种线程池。只是一个建议
  • 如果主线程已经在监听事件,为什么子线程不能只向主线程发送一个事件,表明它已经完成了?然后只有主线程会接触容器,不需要同步。
  • @AlexanderKondratskiy 我知道,但这是一个有意识的选择。我没有很多东西进来,子线程可能需要相当长的时间才能完成,所以我认为还没有必要使用线程池。
  • @ildjarn 问题是,这些事件不是在应用程序代码中生成的,它们是由第三方库生成的事件。我无法控制这些事件(即无法触发它们)。
  • 您是否绝对需要等待线程完成,是否有一些绑定到它们的资源绝对需要明确地关闭/停止/最终确定?

标签: c++ multithreading c++11 atomic


【解决方案1】:

我会选择使用线程计数器,并结合条件等待。退出的最后一个线程应该向条件变量发出信号以唤醒服务员。

// the waiter
{
    std::lock_guard<std::mutex> g(threads_lock);
    while (threads > 0) {
        threads_cond.wait(threads_lock);
    }
}
//...

// the threads that are exiting
if (--threads == 0) {
    std::lock_guard<std::mutex> g(threads_lock);
    threads_cond.notify_one();
}

这是假设threadsstd::atomic,当然。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-31
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    • 2016-01-23
    • 2017-10-17
    相关资源
    最近更新 更多