获取一个std :: thread来分离并终止自身

时间:2012-02-02 18:19:47

标签: c++ multithreading

我目前正在开发一个基本的线程池。我使用了c ++ 11的std::thread,以及std::condition_variablestd::unique_lock。它似乎工作,我现在希望能够杀死一些线程,当太多的线程不活动时。 目前,他们的工作是通过std::queue boost::function来完成的。我想添加一堆空的boost::function,所以线程知道他们必须退出循环。 线程的循环是这样的:

void    ThreadPool::threadLoop()
{
  boost::function<void ()>      oThreadTask;
  std::unique_lock<std::mutex>  oLock(m_oTaskMutex);

  while (1)
    {
      // m_oCV is a static std::condition_variable
      // m_oTaskQueue is a static std::queue< boost::function<void ()> >
      m_oCV.wait(oLock, [](){ return m_oTaskQueue.size(); });
      oThreadTask = m_oTaskQueue.front();
      m_oTaskQueue.pop();
      m_oTaskMutex.unlock();
      if (oThreadTask.empty())
        break ;
      oThreadTask();
    }
  // ??
}

问题是,一旦我退出循环,我不确定如何正确分离线程。 查找线程的句柄是否干净(我可以访问std::list<std::thread*>,并可以将它们的ID与std::this_thread::get_id()进行比较),从线程本身调用detach()是否安全,甚至join()

1 个答案:

答案 0 :(得分:11)

是的,如果你已经存储了所有线程对象,你可以找到thread::id等于this_thread::get_id()的那个,你可以在其上调用detach(),并销毁线程对象之后(C ++ 11标准没有阻止这一点,我相信它是基于通常的做法)。确保没有其他执行线程访问被销毁的std::thread实例。

但你不能从线程本身调用join():尝试线程与自身连接会导致死锁,而C ++ 11实现应该识别它并抛出system_error错误条件为resource_deadlock_would_occur

或者,您可以将消息(例如,通过std :: atomic变量)留给主线程,与std::thread的特定实例关联的线程即将完成其执行,并让主线程稍后加入此实例。