C++Asio库学习 Timer.4~5

突破编程_C++_网络编程(Boost.Asio(简介)) Boost.Asio(简介) 阅读详情

Timer.4 使用成员函数作为completion handler

在这个例子中,我们将看到如何使用一个类成员函数作为completion handler。这个程序应该与Timer.3 执行相同的操作。

#include <iostream>
#include <asio.hpp>
#include <boost/bind/bind.hpp>

不是像之前例子中定义一个自由函数print作为completion handler,我们现在定义一个printer的类。

class printer{
public:

这个类的构造函数将使用一个io_context对象的引用作为参数,并且使用它初始化timer_成员。这个用来关闭程序的计数器现在也是类的一个成员。

printer(asio::io_context& io)
    : timer_(io,asio::chrono::seconds(1)),
      count_(0){

boost::bind函数对于类成员函数也可以像自由函数那样发挥作用。因为所有非静态类成员函数都有一个隐式的this参数,我们需要向这个函数绑定this。正如timer.3,boost::bind将我们的completion handler转化为一个函数对象,仿佛它有签名void(const asio::error_code&)。

你讲注意到asio::placeholders::error占位符在这里并没有出现,因为print成员函数并不接受一个错误对象作为参数。

timer_.async_wait(boost::bind(&printer::print, this));
}

在这个类的析构函数,我们将打印计数器最后的值。

~printer(){
    std::cout << "Final count is " << count_ << std::endl;
}

这个print成员函数与timer.3的print函数非常相似,除了它现在是在类的数据成员上操作,而不是传入timer和counter作为参数。

void print(){
    if(count_ < 5){
        std::cout << count_ << std::endl;
        ++count_;

        timer_.expires_at(timer_.expiry() + asio::chrono::seconds(1));
        timer.async_wait(boost::bind(&printer::print, this));
    }
}
private:
    asio::steady_timer timer_;
    int count_;
};

主函数比之前简单,如下

int main(){
    asio::io_context io;
    printer p(io);
    io.run();

    return 0;
}

使用标准库bind,如下:

#include <asio.hpp>
#include <iostream>
#include <functional>

class printer {
public:
    printer(asio::io_context& io)
        : timer_(io, 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() + asio::chrono::seconds(1));
            timer_.async_wait(std::bind(&printer::print, this));
        }
    }
private:
    asio::steady_timer timer_;
    int count_;
};

int main(){
    asio::io_context io;
    printer p(io);
    io.run();
    return 0;
}

Timer.5 在多线程程序中同步completion handler

这个示例展示strand类模板的使用来在多线程程序中同步completion handler。先前4个示例避免了handler的同步问题,通过只在一个线程中调用io_context::run()函数。正如你已经知道的,asio库保证了completion handler将只会在当前调用io_context::run()的线程中调用。因此,只在一个线程中调用io_context::run()确保了completion handler不能并发地运行。

单线程方案通常是一个好的起点,但它的负面是一些程序上的限制,尤其是服务器,包括:

  • 很差的灵敏性,当handlers需要花费大量时间完成
  • 不能扩展到多处理器系统

如果你发现自己陷入这些限制中,一个替代的方案是拥有一个线程池来调用io_context::run()。然而,因为这允许handlers并发执行,当handlers可能访问共享或是线程不安全的资源时,我们需要同步的方法。

#include <iostream>
#include <asio.hpp>
#include <boost/bind/bind.hpp>

我们从定义printer类开始。这个类将会扩展为并行执行2个timer。

class printer
{
public:

除了初始化一对asio::steady_timer成员,构造函数也需要初始化strand_成员,这是类型为asio::strandasio::io_context::executor_type的对象。

strand 类模板是一个执行器适配器,可以保证通过它分派的handler,在下一个handler启动之前,一个正在执行的handler将被允许完成。无论调用 io_context::run() 的线程数量有多少,都能保证这一点。当然,处理程序仍有可能与其他处理程序同时执行,而这些处理程序不是通过strand调度的,就是通过不同的strand对象调度的。

  printer(asio::io_context& io)
    : strand_(asio::make_strand(io)),
      timer1_(io, asio::chrono::seconds(1)),
      timer2_(io, asio::chrono::seconds(1)),
      count_(0)
  {

当发起异步操作时,每个completion handler都与一个asio::strandasio::io_context::executor_type对象相关联。这个asio::bind_executor()函数返回一个新的handler,它可以通过strand对象自动分发它所包含的handler。通过将handler绑定到相同的strand,我们确信它们不能并发执行。

    timer1_.async_wait(asio::bind_executor(strand_,
          boost::bind(&printer::print1, this)));

    timer2_.async_wait(asio::bind_executor(strand_,
          boost::bind(&printer::print2, this)));
  }

  ~printer()
  {
    std::cout << "Final count is " << count_ << std::endl;
  }

在一个多线程程序中,如果需要访问共享资源,异步操作的handler应该被同步。在这个示例中,由print1和2使用的共享资源时std::cout和count_成员。

  void print1()
  {
    if (count_ < 10)
    {
      std::cout << "Timer 1: " << count_ << std::endl;
      ++count_;

      timer1_.expires_at(timer1_.expiry() + asio::chrono::seconds(1));

      timer1_.async_wait(asio::bind_executor(strand_,
            boost::bind(&printer::print1, this)));
    }
  }

  void print2()
  {
    if (count_ < 10)
    {
      std::cout << "Timer 2: " << count_ << std::endl;
      ++count_;

      timer2_.expires_at(timer2_.expiry() + asio::chrono::seconds(1));

      timer2_.async_wait(asio::bind_executor(strand_,
            boost::bind(&printer::print2, this)));
    }
  }

private:
  asio::strand<asio::io_context::executor_type> strand_;
  asio::steady_timer timer1_;
  asio::steady_timer timer2_;
  int count_;
};

主函数现在在两个线程中触发io_context::run()函数,一个在主函数中,另一个在额外的线程中。

int main()
{
  asio::io_context io;
  printer p(io);
  asio::thread t(boost::bind(&asio::io_context::run, &io));
  io.run();
  t.join();

  return 0;
}

使用标准库的bind,如下:

#include <asio.hpp>
#include <iostream>
#include <functional>

class printer {
public:
    printer(asio::io_context& io):
        strand_(asio::make_strand(io)),
        timer1_(asio::steady_timer(io, asio::chrono::seconds(1))),
        timer2_(asio::steady_timer(io, asio::chrono::seconds(1))),
        count_(0){
            timer1_.async_wait(asio::bind_executor(strand_, std::bind(&printer::print1, this)));
            timer2_.async_wait(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() + asio::chrono::seconds(1));
            timer1_.async_wait(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() + asio::chrono::seconds(1));
            timer2_.async_wait(asio::bind_executor(strand_, std::bind(&printer::print2, this)));
        }
    }
private:
    asio::strand<asio::io_context::executor_type> strand_;
    asio::steady_timer timer1_;
    asio::steady_timer timer2_;
    int count_;
};

int main(){
    asio::io_context io;
    printer p(io);
    asio::thread t([&io](){ io.run(); });
    io.run();
    t.join();
    return 0;
}
C++构建智慧城市道路巡检平台:微服务架构与高性能实战 微服务架构通过将单体应用拆分为独立部署、松耦合的服务,提升了系统的可扩展性和可维护性。其核心原理在于服务自治和基于API或事件进行通信。在需要处理海量实时数据和高并发请求的场景下,这种架构的价值尤为凸显,例如在智慧城市、物联网和边缘计算领域。C++凭借其卓越的运行时性能和精细的资源控制能力,成为实现高性能微服务的理想选择。通过结合Boost.Asio进行异步网络编程、利用Apache Kafka实现事件驱动通信,并集成PostGIS处理地理空间数据,可以构建出能够应对千万级终端接入和低延迟分析需求的坚实系统 阅读详情

相关推荐

基于Sogou C++ Workflow的10分钟高性能微服务搭建指南

异步编程是构建高性能网络服务的核心技术,它通过非阻塞I/O和事件驱动机制,在单线程内高效处理大量并发连接,从而显著提升系统吞吐量和资源利用率。其核心原理在于将耗时的I/O操作交由系统内核处理,程序在等待期间可继续执行其他任务,通过回调或协程机制实现流程控制。这一技术价值在于能以更少的资源支撑更高的并发,尤其适合微服务、API网关、实时通信等场景。Sogou C++ Workflow框架正是这一理念的优秀实践,它将网络、计算、文件等操作统一抽象为任务,通过序列、并行等原语组织工作流,让开发者能以同步的思维编写

weixin_34416754的博客 399

C/C++ 网络库 boost asio 使用详解

主要讲解C/C++准标准库中的网络库asio中,掌握以及理解基本的tcp、udp的同步与异步网络编程方法

余识- 1万+

Windows C++微秒级定时器实现:QueryPerformanceCounter实战与调优

在实时系统和性能敏感应用中,高精度定时是核心技术需求。其原理依赖于操作系统提供的高分辨率时间源,通过精确测量时间间隔来控制任务执行时序。这项技术的核心价值在于提升系统响应实时性、保证数据处理连贯性,尤其在高频交易、音视频同步、工业控制等场景中至关重要。Windows平台为实现微秒级定时提供了多种底层机制,其中基于硬件性能计数器的方案因其高精度和稳定性成为现代应用的首选。本文将深入探讨如何利用QueryPerformanceCounter实现微秒级定时器,并分析影响精度的关键因素,为开发者提供一套兼顾精度与C

weixin_34186128的博客 414

一篇搞定ASIO

跟着官方例子走 第一部分 timer 异步timer #include <asio.hpp> #include <iostream> using namespace std; using namespace asio; void print(const error_code &err) { cout << "Hello Wolrd" &lt...

weixin_42881084的博客 4565

ROS2 Windows原生安装与工业部署实战指南

ROS2作为新一代机器人中间件,其跨平台能力在Windows生态中具有不可替代的工程价值。本文从ROS2在Windows上的核心原理切入,解析MSVC编译链、Chocolatey系统依赖管理、Visual Studio工具链协同等底层机制,阐明为何原生Windows支持比WSL2方案更契合实时控制、USB直通、GUI集成与产线交付等刚性需求。技术价值体现在稳定构建(colcon+VS)、可靠运行(rclpy/rclcpp原生适配)和便捷部署(PyInstaller打包、Windows服务化)。典型应用场景覆

weixin_30647065的博客 482

【C++】开源:Boost网络库Asio配置使用

Boost网络库Asio配置使用

DevFrank的博客 4756

Asio C++零基础入门(一):Asio C++库详细介绍

Asio是C++中用于网络和低级I/O编程的跨平台库,提供高效的异步编程模型。它支持回调函数、Future/Promise和协程三种异步模式,涵盖TCP/UDP/ICMP等网络协议、定时器、串口通信和信号处理。Asio通过事件驱动实现高并发,避免线程开销,兼容Linux(epoll)、Windows(IOCP)等系统。其优势包括高性能、现代C++接口、工业级稳定性和灵活应用场景。提供Boost.Asio和独立版本两种选择,满足不同项目需求。

追求卓越 3490

【基于 Asio 协程的高精度定时器设计与实现】

本文从设计到实现完整展示了一个基于 Asio 协程的高精度定时器采用绝对时间点调度避免漂移。通过系统 API 提升时钟分辨率与线程优先级。利用协程简化异步编程模型。该定时器已在我司项目中稳定运行,支持 15ms 级周期任务,效果优异。如果你也在寻找一个高效、精准、易用的 C++ 定时器实现,不妨参考本文思路,或直接使用提供的CAsioTimer类。项目源码:已整合到公司内部库,若需完整可运行示例,欢迎留言交流。日期:2026-08-14原文发布于 优快云,转载请注明出处。

weixin_45397344的博客 367

C++Asio库学习 Timer.1~3

直接解压源码,例如从官网https://sourceforge.net/projects/asio/files/asio/1.28.0%20%28Stable%29/ 下载。之后,使用如下命令编译程序,其中path-to-asio为asio文件所在路径。

destiny44123的博客 1797

【4】gpio

导出GPIO: (linux内核自带)执行完以上命令后,如果该gpio接口存在且未被占用则会出现如下目录:/sys/class/gpio/gpio943# 设置方向:in:表示该gpio用于输入。(如该gpio连接一个按钮, in时get value合理 )out:表示该gpio用于输出。(如该gpio连接一个led灯, out才能set value, out能get value,但是哪边gpio强就是哪边的值,所以out时get value不合理)

持续更新ing... 922

【16】linux命令/工具,systemd,文件操作,动静态库,信号,socket

apt install python3-pip --fix-missing(断开vpn,cp /etc/apt/sources.list /etc/apt/sources.list.bak,python3 -m pip install --upgrade pip,apt-get update,pip install 包名 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com)设置时间,联网,apt-get install vim。

持续更新ing... 6788

C++ WebSocket服务实战:基于WebSocket++与Asio构建高性能实时通信后端

WebSocket作为一种在单个TCP连接上进行全双工通信的网络协议,其核心原理是通过HTTP升级握手建立持久连接,实现服务器与客户端之间的低延迟、双向实时数据交换。这一技术为需要高实时性的应用场景提供了基础通信能力,具有显著的技术价值,尤其适用于在线游戏、实时数据监控、即时通讯和协同编辑等对响应速度和并发处理要求高的领域。在工程实践中,C++因其对系统资源的精细控制和出色的运行时性能,常被选作构建此类高性能服务的语言。本文聚焦于使用纯头文件库WebSocket++结合Asio网络库,从环境搭建、事件驱动模

weixin_34176694的博客 467

视频监控设备(NVR、IPC等)如何通过国标GB28181接入到视频监控平台,以及接入过程如何测试视频接入是否成功

GB/T28181标准广泛的应用,视频监控设备通过国标GB28181接入视频监控平台的过程变成程序化、标准化的互联过程,确保了视频监控设备能够在不同系统、不同网络环境下实现远程、跨区域、跨级别的访问和控制。版本有GB28181-2011、2016、2022几个常用版本,威迪斯特的视频监控平台完全支持GB28181的这几个版本,能够实现不同品牌视频监控设备的国标视频接入(国标视频监控接入),或者为国标28181视频接入(国标28181视频监控接入),也为国标281818接入(国标GB/T28181接入。

weixin_70208651的博客 1万+

Windows平台Boost库1.69.0配置与使用指南

Boost库作为C++标准库的重要补充,提供了丰富的跨平台组件支持。其核心原理通过模板元编程和二进制库混合部署,为开发者提供高性能解决方案。在Windows开发环境中,Visual Studio与Boost的集成需要特别注意包含路径设置和运行时库匹配。典型应用场景包括正则表达式处理、文件系统操作和类型安全编程等。针对Boost 1.69.0版本,特别需要掌握头文件库与二进制库的差异化配置方法,以及如何解决常见的编译链接问题。通过合理配置预编译头和多版本管理,可以显著提升大型项目的开发效率。

weixin_30660027的博客 414

Oracle 11g RAC 节点通信故障排查与修复指南

本文详细介绍了Oracle 11g RAC集群发生节点通信故障时的系统性排查与修复方法。当出现节点异常重启时,核心问题往往源于心跳网络中断。文章提供了从快速诊断、日志分析到六层深度检查的完整指南,并给出了针对网络配置、内核参数及Oracle已知Bug等常见根因的实战解决方案,帮助DBA快速恢复集群稳定。

weixin_29246195的博客 273

深入解析:el-table合并单元格

  在企业级应用开发中,我们经常需要处理复杂的数据展示需求。在构建复杂的数据展示后台时,我们常常需要将表格中具有相同属性的行进行视觉上的合并,以提升信息的聚合度和可读性。在 Element Plus 的 el-table 组件中,span-method 属性是实现单元格合并的核心机制,允许开发者自定义单元格的合并逻辑,开发者可以通过实现自定义合并策略来满足各种负责需求。  合并行的本质是通过计算相邻行数据的相似性,确定满足合并的单元格范围,然后通过 DOM 操作将多个单元格合并为一个。这种操作在前端数据可视

独泪了无痕 229

c++总结(持续更新中)

1、c++的默认继承方式为private。

多看多听多总结 463

基于阻抗控制的工业机器人轨迹跟踪系统 Simulink/Simscape 仿真

  本文是对文献 [1] 的复现。 关于阻抗控制   阻抗控制的提出可以追溯到 1984 年,Neville Hogan 在 American Control Conference 发表的 Impedance Control:An Approach to Manipulation ,次年,Hogan N. 又在 Journal of Dynamic Systems Measurement and Control-transactions of The Asme 发表了阻抗控制经典三部曲 —— Imped.

-贝塔- 的博客 2万+

C++主题统计:零拷贝哈希与无锁分片实现

在消息中间件与实时系统中,主题(topic)统计是保障可观测性的基础能力,其本质是面向高并发、低延迟场景的轻量级计数与状态聚合。核心原理在于规避字符串哈希运行时开销、消除锁竞争、控制内存碎片,并通过编译期哈希、原子操作分片、弱引用生命周期管理等C++特有机制达成纳秒级统计性能。该技术显著提升ROS 2、DDS、MQTT网关及IoT边缘总线的故障定位效率与SRE响应速度,适用于资源受限的ARM嵌入式环境与毫秒级控制闭环系统,是工业级C++通信基础设施中不可或缺的可观测性落地组件。

weixin_30394669的博客 533

YOLOv11多模态融合实战:基于YOLOFuse的RGB与红外线(IR)协同检测技术解析

本文深入解析了基于YOLOv11的YOLOFuse多模态融合技术,重点探讨了RGB与红外线(IR)协同检测的实现原理与实战应用。文章详细介绍了双流架构与数据级、特征级、决策级三种融合策略,并通过实战案例展示了其在低光照、复杂环境下显著提升检测精度与鲁棒性的优势,为全天候安防、自动驾驶等场景提供了有效的技术解决方案。

weixin_29041195的博客 650

Windows 10/11蓝屏急救:SECURE_PCI_CONFIG_SPACE_ACCESS_VIOLATION报错全攻略(附安全模式+CMD修复)

本文针对Windows 10/11系统常见的SECURE_PCI_CONFIG_SPACE_ACCESS_VIOLATION蓝屏报错,提供了从诊断到修复的完整解决方案。文章深入剖析了该错误与系统安全功能“内存完整性”及pci.sys驱动的关系,并详细指导用户如何通过安全模式进行基础修复,以及使用命令提示符执行高级系统文件修复和注册表修改,帮助用户彻底解决蓝屏问题并恢复系统稳定。

echo99的专栏 968

ROS C++开发必学:NodeHandle核心原理与工业级实践

NodeHandle是ROS C++通信机制的基石,本质是一个有状态、带作用域的资源管理器,而非简单句柄。它封装节点注册、话题/服务生命周期、回调队列调度及参数服务器访问等关键能力。理解其构造方式(默认/命名空间/父子嵌套/自定义队列)、作用域语义与析构行为,是避免Segmentation fault、Failed to contact master等高频崩溃的前提。在机器人系统中,合理运用多命名空间NodeHandle和独立回调队列,可实现传感器、执行器与控制逻辑的线程安全隔离。本文聚焦ROS 1(ros

weixin_33928137的博客 326

OpenClaw实战系列06:持久记忆与RAG知识库构建——让AI真正“记住”你

本文介绍了OpenClaw AI助理的持久记忆与RAG知识库构建功能。OpenClaw采用"文件即真理"的独特设计,所有记忆都以Markdown文件形式存储,支持直接编辑和Git版本管理。记忆系统分为三层:长期精炼记忆(MEMORY.md)、日常日志(按日期存储)和归档记忆。文章详细说明了环境配置步骤,包括安装必要组件、创建目录结构、设置API密钥,并提供了OpenClaw主配置文件的完整参数说明。该系统实现了跨会话、跨平台的持久化记忆,使AI助理能真正理解用户需求。

PeterPan的博客 1171

协程框架高并发翻车了?三个C++ Web框架实测,结果出乎意料

对 Hical、Drogon、Cinatra 三个 C++ Web 框架进行高并发压测对比,揭示协程模型在万级连接下的性能瓶颈。

Hical的博客 587

Unity零基础到入门 ☀️| 【UI系统学习】轻松学会 Unity 的 UGUI基础控件的使用(包括一个简易血条、蓝条设计)

Unity,UGUI。本篇博客来挑几种Unity中最常用的UI控件如何使用和使用技巧,包括一个简易血条蓝条的小实例

努力前行,总会成为自己心中的那道光 2万+

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Ubuntu 20.04源码编译ROS2 Foxy完整指南

ROS2是面向机器人系统的中间件框架,其核心依赖于DDS通信、C++运行时(rclcpp)与构建工具链(colcon)的深度协同。源码编译ROS2的本质,是掌握从底层ABI兼容性(如GCC 9.3、libboost、libasio)到高层抽象(RMW中间件、QoS策略)的全栈原理。相比预编译二进制包,源码安装可规避fastcdr版本冲突、segmentation fault等典型环境故障,支撑调试、定制DDS实现及ARM64等跨平台部署。本指南聚焦Ubuntu 20.04+Foxy LTS组合,覆盖loca

cuiji1279的博客 448

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

上一篇: C++Asio库学习 Timer.1~3
下一篇: [PFPL] Ch 6. 学习
destiny44123
博客等级 码龄7年 119粉丝 16原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值