C++ 如何在调用C+时通过阻塞调用优雅地停止/销毁线程+;析构函数?
在下面的类中,工作线程在构造函数中启动。 工作进程有一个对队列的阻塞调用 它按预期工作,但当C++ 如何在调用C+时通过阻塞调用优雅地停止/销毁线程+;析构函数?,c++,multithreading,destructor,stdthread,blockingqueue,C++,Multithreading,Destructor,Stdthread,Blockingqueue,在下面的类中,工作线程在构造函数中启动。 工作进程有一个对队列的阻塞调用 它按预期工作,但当AsyncQueue对象超出范围时(无论出于何种原因),将调用其析构函数。此外,还调用了simple_queue对象的析构函数(我通过调试检查的内容) 但是工人会怎么样呢?因为它还在等待对队列的阻塞调用 我观察到,没有调用impl_thread_uu.detach()执行崩溃。 然而,我不知道这是否是一个解决方案。另外,我不明白的是:尽管队列对象被销毁,但阻塞调用并没有引发异常——事实上,我在catch处
AsyncQueue
对象超出范围时(无论出于何种原因),将调用其析构函数。此外,还调用了simple_queue对象的析构函数(我通过调试检查的内容)
但是工人会怎么样呢?因为它还在等待对队列的阻塞调用
我观察到,没有调用impl_thread_uu.detach()析构函数内的代码>执行崩溃。
然而,我不知道这是否是一个解决方案。另外,我不明白的是:尽管队列对象被销毁,但阻塞调用并没有引发异常——事实上,我在catch处理程序中设置了一个断点。那么,这里发生了什么?实现该场景的正确方法是什么?我深深地感觉到,我在这里所做的并不完全是我应该做的;-)
模板
类异步队列
{
公众:
AsyncQueue():impl\u线程(&AsyncQueue::worker,this)
{
tq_uu=std::shared_ptr(新的简单队列);
impl_thread_uu.detach();
}
//~AsyncQueue()=默认值;
~AsyncQueue(){
std::cout如果可以的话,最简单的方法是在析构函数中发送eq队列中的停止令牌,并检查worker中的停止令牌以退出它。首先移除分离
~AsyncQueue() {
_eq.add(stopToken); // what ever your can use here. else use an atomic bool
std::cout << "[" << boost::this_thread::get_id() << "] destructor AsyncQueue" << std::endl;
impl_thread_.join();
}
~AsyncQueue(){
_eq.add(stopToken);//您可以在这里使用什么。否则使用原子布尔
std::cout Question OT:我认为这不是启动线程的安全方法::impl_thread\uu(&AsyncQueue::worker,this)
。问题是,如果以后在构造函数中抛出异常(例如从new
),可以调用joinable thread的析构函数impl_thread
,这将导致std::terminate
。不要添加没有任何值的代码(这两个函数在析构函数和catch块中返回)。只要最后一个表达式运行,您就可以从函数返回。在保证设置该成员之前,您的线程启动并访问tq
。另外,tq
是共享指针有什么特殊原因吗?只需使用普通对象。在impl\u thread
之前声明时,您还可以解决争用条件@Ulrich:是的,你是对的。但是,修改构造函数并不能解决我的问题,这更像是破坏。使用普通对象而不是共享指针也不行。
~AsyncQueue() {
_eq.add(stopToken); // what ever your can use here. else use an atomic bool
std::cout << "[" << boost::this_thread::get_id() << "] destructor AsyncQueue" << std::endl;
impl_thread_.join();
}