混合boost :: asio和boost :: signals2会产生问题

时间:2013-10-20 10:59:14

标签: c++ multithreading boost

{boost 1.54}

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

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();从而从Async的m_sig删除插槽然后从本地范围出来时,对shared_ptr到Process的最后一个剩余引用将会死亡,从而销毁它,但是到那时其他线程触发m_sig可能已经输入Process::slot()并且即将执行标记为&lt; 1&gt;的行。以上。 signal2是否保证在完全执行插槽之前不会删除插槽?

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

0 个答案:

没有答案