加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 09:34:04 所属栏目:百科 来源:网络整理
导读:我正在运行一些需要异步通信的测试,底层框架是Asio.有时,即使测试已经被删除,处理程序也会保留在处理循环中,这是有充分理由的.但是,在删除目标后调用它. 测试类: virtual void SetUp(){ _client = new Client; _server = new Server; Service::run();}virtu
我正在运行一些需要异步通信的测试,底层框架是Asio.有时,即使测试已经被删除,处理程序也会保留在处理循环中,这是有充分理由的.但是,在删除目标后调用它.

测试类:

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

  Service::run();
}

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

  delete _client;
  delete _server;
}

服务类:

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

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

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

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

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

解决方法

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

The destruction sequence described
above permits programs to simplify
their resource management by using
shared_ptr<>. Where an object’s
lifetime is tied to the lifetime of a
connection (or some other sequence of
asynchronous operations),a shared_ptr
to the object would be bound into the
handlers for all asynchronous
operations associated with it. This
works as follows:

  • When a single connection ends,all associated asynchronous operations
    complete. The corresponding handler
    objects are destroyed,and all
    shared_ptr references to the objects
    are destroyed.
  • To shut down the whole program,the io_service function stop() is called
    to terminate any run() calls as soon
    as possible. The io_service destructor
    defined above destroys all handlers,
    causing all shared_ptr references to
    all connection objects to be
    destroyed.

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

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
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读