C++async_wait的使用(C++asio网络库相关)

async_wait的使用
async_wait传参数绑定事件调用回调函数及C++指针的黑暗面


async_wait传参数调用回调函数通过bind方式绑定,可以用lambda表达式代替。
本来调用一次print就会失效,可以通过expires_at定义下一次的失效时间来多次执行print
需要占一位参数error_code是系统参数
async_wait形参只有一个所以需要bind绑定函数和函数参数
以lambda方式效率更高

#include
#include
#include
#include
#include
// boost::function<>
// std::function<>

void print(const boost::system::error_code & /* e*/,
           std::shared_ptr t, int *count) {
  if (*count < 5) {
    std::cout << *count << std::endl;
    ++(*count);

    t->expires_at(t->expires_at() + boost::posix_time::seconds(1));
    t->async_wait([t, count](const auto &error) { print(error, t, count); });
  }
}

void callback(const boost::system::error_code& e) {
    std::cout << "hello world\n";
}

std::shared_ptr
registerPrint(boost::asio::io_service &io, int *count) {
  auto t = std::make_shared(
      io, boost::posix_time::seconds(1));
  t->async_wait([t, count](const auto &error) { print(error, t, count); });
  return t;
}

int main() {
  boost::asio::io_service io;

    std::vector v;
    for(int i = 0;i < 5; ++i) v.push_back(i);
    for (int i = 0; i < 5; ++i) {
        auto t = registerPrint(io, &v[i]);
        std::cout <<"pointer address is: " << t.get() << std::endl;
    }
  io.run();
    for(int i = 0; i < 5; ++i)
  std::cout << "Final count is " << v[i] << std::endl;

  return 0;
}

回调绑定的参数生命周期一定要足够长保证在run能够运行
如以下情况run会调用智能指针的野指针因为已经超过出了智能指针的生命周期,但不一定会出错这也是C++黑暗的一面,尽管指针已经成为了野指针但依然保留了new时的结构

C++async_wait的使用(C++asio网络库相关)_第1张图片C++async_wait的使用(C++asio网络库相关)_第2张图片

用vector容器打印可发现内容已经是错误的

 C++async_wait的使用(C++asio网络库相关)_第3张图片

 C++async_wait的使用(C++asio网络库相关)_第4张图片

 

用lambda+智能指针方式作为async_wait回调参数来延长参数生命周期及lambda本质
lambda函数本质:
遵循了类的特征,生命周期和类是一样的
如果有参数传入好比类的成员变量
传入引用就是引用本身的生命周期

C++async_wait的使用(C++asio网络库相关)_第5张图片不用绑定原生指针

 C++async_wait的使用(C++asio网络库相关)_第6张图片

 

可以通过在lambda绑定智能指针来延长生命周期

C++async_wait的使用(C++asio网络库相关)_第7张图片C++async_wait的使用(C++asio网络库相关)_第8张图片

 

但有的时候并不希望事件回调参数有如此长的生命周期希望外部来控制
还有一个弊端也改变了外部函数接口,上面例子必须要传入智能指针。。
智能指针有传染性,一个地方要用智能指针,很多地方都被迫用智能指针

 

async_wait事件绑定成员函数的方式及通过错误码判断回调参数是否失效
async_wait事件绑定成员函数的方式:
this是函数的调用者

C++async_wait的使用(C++asio网络库相关)_第9张图片

以lambda方式

 C++async_wait的使用(C++asio网络库相关)_第10张图片

 在类中this指针是始终有效的
有很多BUG都是调回调函数时绑定参数已经失效了
在析构的时候把所有绑定的事件的回调函数都取消掉用timer_.cancel()是没用的因为已经晚了

可以通过对错误码的判断让代码变得安全一些

C++async_wait的使用(C++asio网络库相关)_第11张图片

 

————————————————
版权声明:本文为CSDN博主「昔拉天使」的原创文章
原文链接:https://blog.csdn.net/qq_39885372/article/details/104054423

你可能感兴趣的:(c++,开发语言)