C++ 混合boost::asio和boost::signals2产生问题

C++ 混合boost::asio和boost::signals2产生问题,c++,multithreading,boost,C++,Multithreading,Boost,{boost 1.54} 所有asio操作都发生在同一io_服务上,该服务的run()由多个std::threads调用(因此是一个线程池) struct Async:std::从\u中启用\u共享\u { 升压::信号2::信号m_信号; 无效读取() { auto self=shared_from_this(); boost::asio::异步读取( /*插座*/, /*bufferToCollectData*/,, /*分隔符*/, [self]{self->onRead(..);} );

{boost 1.54}

所有asio操作都发生在同一io_服务上,该服务的run()由多个std::threads调用(因此是一个线程池)

struct Async:std::从\u中启用\u共享\u
{
升压::信号2::信号m_信号;
无效读取()
{
auto self=shared_from_this();
boost::asio::异步读取(
/*插座*/,
/*bufferToCollectData*/,,
/*分隔符*/,
[self]{self->onRead(..);}
);
}
读取时无效(…)
{
m_sig();
}
};
结构进程:std::从\u中启用\u共享\u
{
std::共享\u ptr m_shrPtrAsync;
boost::signals2::连接m_连接;
void start()
{
m_shrPtrAsync=std::make_shared();
//m_shrPtrAsync->startUpThings();
auto self=shared_from_this();
m_connection=m_shrPtrAsync->m_sig.connect(
[self]{self->slot();}
);
}
无效停止()
{
//这将不会删除插槽,并且必须无限期地等待,直到m_sig上发生某些操作。
//------------------------------- 
m_连接。断开();
//这将强制删除原始插槽。
m_connection=m_shrPtrAsync->m_sig.connect([this]{dummy();});
m_连接。断开();
}
void dummy(){}
空槽()
{
auto self=shared_from_this();//------------
//不阻止调用线程(异步的m_sig())
m_strand.post(
[self]{self->slotPrivateImpl();}
);
}
void slotPrivateImpl(){/*处理*/}
};
//这来自线程池外的主线程
{//局部作用域开始
自动shrPtrProcess=std::使_共享();
shrPtrProcess->start();
//过一会儿
shrPtrProcess->stop();
}//局部范围结束。我希望shrPtrProcess删除此处包含的指针
//这将依次删除shrPtrProcess->m_shrPtrAsync中的异步指针
这安全吗?当主线程执行
shrPtrProcess->stop()时
因此从异步的
m_sig
中删除插槽,然后退出本地范围,对
进程
的共享ptr的最后剩余引用将终止,从而销毁它,但是其他线程触发
m_sig
可能已经进入
进程::插槽(
)到那时,即将执行上面标记的行。信号2是否保证插槽在完全执行之前不会被删除


如果这是不安全的,那么如何实现
shrPtrProcess
销毁
Process
ptr的这种行为,从而在本地作用域结束后销毁
Async
中的
Async
原始ptr?如果我不在上面标记的地方进行黑客攻击,如果m_sig()不再发射,我将永远无法释放资源,因为
signals2::connection::disconnect()
不会立即删除插槽。

据我所知,您总是通过
shared\u ptr
调用
插槽(),因此,此时至少有一个引用处于活动状态。顺便说一句,这是有效的-dtor被调用。根据我在其他帖子中读到的内容,signal在调用之前复制了插槽列表。因此,当signal执行slot()并调用stop()时,hack at mark会删除原始slot functor,当slot()在发布sloprivatempl()以执行进一步任务后返回时,临时functor副本也会被销毁,现在只有一个引用将在sloprivatempl()后过期执行结束,然后将调用dtor-引用和
struct Async : std::enable_shared_from_this<Async>
{
   boost::signals2::signal<void()> m_sig;

   void read()
   {
      auto self = shared_from_this();
      boost::asio::async_read_until(
               /*socket*/,
               /*bufferToCollectData*/,
               /*delimiter*/,
               [self]{self->onRead(..);}
               );
   }

   void onRead(..)
   {
      m_sig();
   }
};

struct Process : std::enable_shared_from_this<Process>
{
   std::shared_ptr<Async> m_shrPtrAsync;
   boost::signals2::connection m_connection;

   void start()
   {
      m_shrPtrAsync = std::make_shared<Async>();
      //m_shrPtrAsync->startUpThings();

      auto self = shared_from_this();
      m_connection = m_shrPtrAsync->m_sig.connect(
               [self]{self->slot();}
               );
   }

   void stop()
   {
      //this will not delete the slot and have to wait indefinitely until some operation happens on m_sig.
      //------------------------------- <2>
      m_connection.disconnect();

      //this should force the original slot deletion.
      m_connection = m_shrPtrAsync->m_sig.connect([this]{dummy();});
      m_connection.disconnect();
   }

   void dummy() {}

   void slot()
   {
      auto self = shared_from_this(); //-------------------- <1>
      //to not block the calling thread (Async's m_sig())
      m_strand.post(
               [self]{self->slotPrivateImpl();}
               );
   }

   void slotPrivateImpl() { /*Processing*/ }
};

//This is from the main thread outside the thread-pool
{//local scope begins
auto shrPtrProcess = std::make_shared<Process>();
shrPtrProcess->start();
//after sometime
shrPtrProcess->stop();
}//local scope ends. I want shrPtrProcess to delete the contained pointer here
//which should in turn delete the Async's pointer in shrPtrProcess->m_shrPtrAsync