当前位置: 首页 > news >正文

【Boost】Asio库学习(一)

Boost::Asio

同步使用计时器

  • 所有使用asio的程序都需要至少有一个I/O执行上下文,例如io_contextthread_pool对象。I/O执行上下文提供对I/O功能的访问。
#include <iostream>
#include <boost/asio.hpp>int main()
{boost::asio::io_context io;boost::asio::steady_timer t(io, boost::asio::chrono::seconds(5));t.wait();std::cout << "Hello, world!" << std::endl;return 0;
}
  • boost::asio::steady_timer::wait()timer过期后返回,也就是在timer创建5s后,而不是在wait()调用5s后。timer只有两种状态,过期和未过期。如果wait()是一个过期的timer调用,那么会立即返回。

异步使用计时器

  • timer不实用阻塞wait(),调用steady_timer::async_wait()实现异步,被调用函数签名void(const boost::system::error_code&),最后必须调用boost::asio::io_context::run()成员函数。
#include <iostream>
#include <boost/asio.hpp>void print(const boost::system::error_code& /*e*/)
{std::cout << "Hello, world!" << std::endl;
}int main()
{boost::asio::io_context io;boost::asio::steady_timer t(io, boost::asio::chrono::seconds(5));t.async_wait(&print);io.run();return 0;
}
  • boost::asio::io_context没有任务之后才会停止,io_context绑定了timer,也就是timer过期以及print函数返回前,会一直执行。

绑定参数

  • 实现一个重复的计时器,还需要传递两个参数到处理函数,一个是timer的指针,还有一个是停止条件参数。 std::bind()函数可以绑定参数并将函数正确转化为void(const boost::system::error_code&)签名的函数,需要确认参数列表对应。
#include <functional>
#include <iostream>
#include <boost/asio.hpp>void print(const boost::system::error_code& /*e*/,boost::asio::steady_timer* t, int* count)
{if (*count < 5){std::cout << *count << std::endl;++(*count);t->expires_at(t->expiry() + boost::asio::chrono::seconds(1));t->async_wait(std::bind(print,boost::asio::placeholders::error, t, count));}
}int main()
{boost::asio::io_context io;int count = 0;boost::asio::steady_timer t(io, boost::asio::chrono::seconds(1));t.async_wait(std::bind(print,boost::asio::placeholders::error, &t, &count));io.run();std::cout << "Final count is " << count << std::endl;return 0;
}

将成员函数用作处理函数

  • 创建一个类,这个类有一个boost::asio::io_context对象引用,当初始化timer时使用。非静态函数有一个隐性指针this,需要绑定到成员函数,std::bind()函数将成员函数转换为一个可以被调用的函数对象,函数签名void(const boost::system::error_code&)
#include <functional>
#include <iostream>
#include <boost/asio.hpp>class printer
{
public:printer(boost::asio::io_context& io): timer_(io, boost::asio::chrono::seconds(1)),count_(0){timer_.async_wait(std::bind(&printer::print, this));}~printer(){std::cout << "Final count is " << count_ << std::endl;}void print(){if (count_ < 5){std::cout << count_ << std::endl;++count_;timer_.expires_at(timer_.expiry() + boost::asio::chrono::seconds(1));timer_.async_wait(std::bind(&printer::print, this));}}private:boost::asio::steady_timer timer_;int count_;
};int main()
{boost::asio::io_context io;printer p(io);io.run();return 0;
}

多线程程序中同步

  • 使用strand类模版,除了初始化boost::asio::steady_timer成员,也要初始化strand成员,boost::asio::strand<boost::asio::io_context::executor_type>对象,strand保证它分配的执行器,一个正在执行的可以在下一个处理之前完成,而不用管调用boost::asio::io_context的线程数量。将程序绑定到同一个strand,可以保证程序不并发执行。
#include <functional>
#include <iostream>
#include <thread>
#include <boost/asio.hpp>class printer
{
public:printer(boost::asio::io_context& io): strand_(boost::asio::make_strand(io)),timer1_(io, boost::asio::chrono::seconds(1)),timer2_(io, boost::asio::chrono::seconds(1)),count_(0){timer1_.async_wait(boost::asio::bind_executor(strand_,std::bind(&printer::print1, this)));timer2_.async_wait(boost::asio::bind_executor(strand_,std::bind(&printer::print2, this)));}~printer(){std::cout << "Final count is " << count_ << std::endl;}void print1(){if (count_ < 10){std::cout << "Timer 1: " << count_ << std::endl;++count_;timer1_.expires_at(timer1_.expiry() + boost::asio::chrono::seconds(1));timer1_.async_wait(boost::asio::bind_executor(strand_,std::bind(&printer::print1, this)));}}void print2(){if (count_ < 10){std::cout << "Timer 2: " << count_ << std::endl;++count_;timer2_.expires_at(timer2_.expiry() + boost::asio::chrono::seconds(1));timer2_.async_wait(boost::asio::bind_executor(strand_,std::bind(&printer::print2, this)));}}private:boost::asio::strand<boost::asio::io_context::executor_type> strand_;boost::asio::steady_timer timer1_;boost::asio::steady_timer timer2_;int count_;
};int main()
{boost::asio::io_context io;printer p(io);std::thread t([&]{ io.run(); });io.run();t.join();return 0;
}

可能的输出:

Timer 2: 0
Timer 1: 1
Timer 2: 2
Timer 1: 3
Timer 2: 4
Timer 1: 5
Timer 2: 6
Timer 1: 7
Timer 2: 8
Timer 1: 9

http://www.mrgr.cn/news/20745.html

相关文章:

  • 号称第一本程序员的Agent入门书籍?《大模型应用开发 动手做AI Agent》来了!
  • 基于SringBoot框架的智慧博物馆预约平台
  • Spark常见面试题整理
  • Java队列详细解释
  • VLDB 2024论文解读丨GaussDB:计算-内存-存储三层池化解耦的多主云原生数据库
  • 基于51单片机的倒计时装置proteus仿真
  • Java高级编程—多线程(完整详解线程的三种实现方式、以及守护线程、出让线程、插入线程、线程声明周期等,附有代码+案例)
  • 零基础入门~汇编语言(第四版王爽)~第4章 第一个程序
  • 前端面试:margin和padding分别适合什么场景使用?
  • 不敢相信,华为智能眼镜2开放式聆听也能做到通话隐私保护了?
  • 如果文件从存储卡中被误删除,存储卡数据恢复如何恢复?
  • 如何进行亚马逊自养号测评?注意事项有哪些?
  • 苹果qq文件过期了怎么恢复?简单4招,拯救你的过期文件
  • 图神经网络基础(1)
  • STM32高级定时器生成互补PWM的原理与代码实现
  • 9月6日星期五今日早报简报微语报早读
  • FreeRTOS 队列 Queue 源码解析
  • AlGC-stable diffusion如何辅助服装设计,SD到底能给设计提升多少效率?
  • SaaS初创企业需求建模指南
  • 先到先得!字节内传380页《从零开始大模型开发与微调基于PyTorch与ChatGLM》学习笔记