0

{提升 1.54}

所有 asio 操作都发生在同一个 io_service 上,它的 run() 从几个 std::threads 调用(因此是一个线程池)

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

这安全吗?当主线程执行shrPtrProcess->stop();从而从异步中删除插槽m_sig然后从本地范围中出来时,对 shared_ptr 的最后一个剩余引用Process将死亡从而破坏它,但其他线程触发m_sig可能已经进入Process::slot() 到那时并即将执行行上面标有<1>。信号2是否保证插槽在完全执行之前不会被删除?

如果这不安全,那么我如何实现这种shrPtrProcess破坏ptr 的行为,一旦本地范围结束Process,又会破坏Async原始 ptr ?shrPtrAsync如果我没有在上面标记为 <2> 的地方进行 hack,如果 m_sig() 不再触发,因为signals2::connection::disconnect()不会导致立即删除插槽,我将永远无法释放资源。

4

0 回答 0