刷新boost :: asio中的所有异步处理程序

War*_*ine 3 c++ boost asynchronous boost-asio

我正在运行一些需要异步通信的测试,底层框架是Asio.有时,即使测试已经被删除,处理程序也会保留在处理循环中,这是有充分理由的.但是,删除目标调用它.

Test类:

virtual void SetUp()
{
  _client = new Client;
  _server = new Server;

  Service::run();
}

virtual void TearDown()
{
  Service::stop();

  delete _client;
  delete _server;
}
Run Code Online (Sandbox Code Playgroud)

Service类:

static void run()
{
  _thread = new asio::thread(boost::bind(&asio::io_service::run, _service));
}

static void stop()
{
  _service->stop();

  _thread->join();
  delete _thread;

  _service->reset();
}
Run Code Online (Sandbox Code Playgroud)

io_service::stop()是非阻塞的,所以在我的情况下它变得毫无用处.如果我删除io_service函数末尾的对象,将不会调用处理程序,但我想要一个更好的解决方案,删除对象之前强制完成.

注意:实际的处理循环是在第二个线程中完成的,但它是在一个io_service::stop()包装器中连接的,整个问题似乎与线程无关.

我正在使用Asio(非Boost)1.4.5,但可以考虑升级(以获得io_service::stopped()操作?).

编辑:io_service根据评论添加包装代码,因为它似乎是相关的.

Sam*_*ler 5

在我看来,你需要稍微重新考虑你的设计.io_service::stop正如你所注意到的那样,确实是异步的.它会导致任何调用io_service::run()尽快返回.boost::asio::error::operation_aborted~io_service()析构函数运行之前,不会调用任何未完成的处理程序.要管理对象生存期,您应该使用a shared_ptr作为文档建议:

上述销毁序列允许程序通过使用shared_ptr <>来简化其资源管理.如果对象的生命周期与连接的生命周期(或其他一些异步操作序列)相关联,则对象的shared_ptr将绑定到与其关联的所有异步操作的处理程序中.其工作原理如下:

  • 当单个连接结束时,所有关联的异步操作都将完成.销毁相应的处理程序对象,并销毁对对象的所有shared_ptr引用.
  • 要关闭整个程序,调用io_service函数stop()以尽快终止所有run()调用.上面定义的io_service析构函数会破坏所有处理程序,导致对所有连接对象的所有shared_ptr引用都被销毁.

更具体地说,你有一个竞争条件

virtual void TearDown()
{
  service->stop();

  // ok, io_service is no longer running
  // what if outstanding handlers use _client or _server ??

  delete _client;
  delete _server;

  // now you have undefined behavior due to a dangling pointer
}
Run Code Online (Sandbox Code Playgroud)