Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在调用C+时通过阻塞调用优雅地停止/销毁线程+;析构函数?_C++_Multithreading_Destructor_Stdthread_Blockingqueue - Fatal编程技术网

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();
}