【问题标题】:How to join all threads before deleting the ThreadPool如何在删除线程池之前加入所有线程
【发布时间】:2018-02-23 14:30:33
【问题描述】:

我正在使用 MultiThreading 类,它在自己的线程池中创建所需数量的线程,并在使用后自行删除。

std::thread *m_pool;      //number of threads according to available cores
std::mutex m_locker;
std::condition_variable m_condition;
std::atomic<bool> m_exit;
int m_processors    

m_pool = new std::thread[m_processors + 1]

void func()
{
   //code
}

for (int i = 0; i < m_processors; i++)
{
    m_pool[i] = std::thread(func);
}

void reset(void)
{
    {
        std::lock_guard<std::mutex> lock(m_locker);
        m_exit = true;
    }
    m_condition.notify_all();

    for(int i = 0; i <= m_processors; i++)
        m_pool[i].join();
    delete[] m_pool;
}

在运行完所有任务后,for 循环应该在delete[] 被执行之前加入所有正在运行的线程。
但似乎最后一个线程仍在运行,而 m_pool 不再存在。
这导致了问题,我不能再关闭我的程序了。
有什么方法可以检查所有线程是否已加入或等待所有线程加入后再删除线程池?

【问题讨论】:

  • 注意你的循环条件i &lt; m_processors ... i &lt;= m_processors

标签: multithreading c++11 mutex


【解决方案1】:

我认为是简单的拼写错误。

具有条件i &lt;= m_processors 的循环是一个错误,实际上会处理数组末尾之后的一个额外条目。这是一个单独的错误。假设 m_processors 为 2。您将拥有一个数组,其中包含 2 个元素,索引为 [0] 和 [1]。但是,您将阅读数组末尾的内容,并尝试与索引 [2] 处的项目连接。 m_pool[2] 是未定义的内存,你可能会崩溃或永远阻塞在那里。

你可能打算i &lt; m_processors

【讨论】:

    【解决方案2】:

    Wick 的回答解决了问题的真正根源。我将使用一些技巧对其进行扩展,这些技巧也可以解决您的问题,同时改进代码的其他方面。

    如果您将 C++11 用于 std::thread,则不应使用 operator new[] 创建线程句柄。使用其他 C++ 结构有更好的方法来做到这一点,这将使一切变得更简单并且异常安全(如果抛出意外异常,您不会泄漏内存)。

    • 将您的线程对象存储在std::vector 中。它将为您管理内存分配和释放(不再有newdelete)。如果您动态插入/删除线程,您可以使用其他更灵活的容器,例如std::list

    • std::generate或类似的方式填充向量


    std::vector<std::thread> m_pool;
    m_pool.reserve(n_processors);
    
    // Fill the vector
    std::generate_n( std::back_inserter(m_pool), m_processors, 
                     [](){ return std::thread(func); } );
    
    • 使用 range-for 循环加入所有元素,并使用容器的函数删除句柄。

    for( std::thread& t: m_pool ) {
      t.join();
    }
    m_pool.clear();
    

    【讨论】:

      猜你喜欢
      • 2020-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-29
      • 2015-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多