我目前正在开发一个基本的线程池。我使用了c ++ 11的std::thread
,以及std::condition_variable
和std::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()
?
答案 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
的特定实例关联的线程即将完成其执行,并让主线程稍后加入此实例。