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

C++编程——异步处理、事件驱动编程和策略模式

异步处理、事件驱动编程、和 策略模式


一、异步处理(Asynchronous Processing)

定义:

异步处理是一种编程模型,允许任务在等待耗时操作(如 I/O、网络请求)完成的同时,不阻塞其他任务的执行。

类比场景:

排队点奶茶 vs 自助取号叫号系统

  • 同步处理: 你在柜台排队点奶茶,等前面的人点完才轮到你。
  • 异步处理: 你在门口的机器上取个号,然后在旁边玩手机,等叫到你再上前点单。

你不必等前面所有人点完才能做别的事(=不会阻塞主线程)。

代码示例(C++ 伪代码):

#include <future>
#include <iostream>int longTask() {std::this_thread::sleep_for(std::chrono::seconds(3));return 42;
}int main() {std::future<int> result = std::async(std::launch::async, longTask);std::cout << "任务开始,我先去做别的事情...\n";// 等待 longTask 完成int value = result.get();std::cout << "任务结果:" << value << std::endl;return 0;
}

二、事件驱动编程(Event-Driven Programming)

定义:

事件驱动是一种编程范式,程序的流程由事件(Event)触发来控制。每当某个事件发生,就调用对应的“事件处理器”。

类比场景:

门铃系统

  • 门口安装了一个门铃(event)。
  • 有人按门铃(事件发生),系统立刻响铃或通知你(事件处理器)。
  • 没人按门铃时,你可以自由做别的事。

你不需要时刻去检测门口是否有人,而是等事件触发你再响应。

代码示例(JavaScript 常见):

document.getElementById("myButton").addEventListener("click", function() {alert("按钮被点击了!");
});

你设置一个事件监听器(Event Listener),当“点击事件”发生时执行某段代码。

C++ 中可以通过回调函数、观察者模式等方式实现类似的事件驱动效果。


三、策略模式(Strategy Pattern)

定义:

策略模式是一种行为设计模式,定义一系列算法,把它们封装起来,并且使它们可以相互替换。客户端不关心具体策略细节,只关注调用统一接口

类比场景:

导航路线选择

  • 你要开车去目的地,可以选择:最快路线最短路线避开收费
  • 不同的策略(开车方式)可以随时切换,但你都只管告诉系统“带我去”。

系统内部选择使用哪个策略,用户无感。

C++ 示例代码:

// 策略接口
class TravelStrategy {
public:virtual void travel() = 0;
};// 具体策略1
class CarStrategy : public TravelStrategy {
public:void travel() override {std::cout << "开车去旅行\n";}
};// 具体策略2
class TrainStrategy : public TravelStrategy {
public:void travel() override {std::cout << "坐火车去旅行\n";}
};// 上下文(使用策略的环境)
class TravelContext {
private:TravelStrategy* strategy;
public:void setStrategy(TravelStrategy* s) {strategy = s;}void go() {strategy->travel();}
};// 使用
int main() {TravelContext ctx;CarStrategy car;TrainStrategy train;ctx.setStrategy(&car);ctx.go(); // 输出:开车去旅行ctx.setStrategy(&train);ctx.go(); // 输出:坐火车去旅行return 0;
}

总结对比表:

名称核心思想类比场景应用场景
异步处理不阻塞当前线程,等待操作完成奶茶取号系统网络通信、文件IO
事件驱动编程响应事件触发,执行特定操作按门铃触发动作UI开发、网络服务器
策略模式行为封装,可随时替换使用方式不同路线导航选择可切换的算法或行为(如排序)

异步处理、事件驱动编程和策略模式 在嵌入式 C++ 中的运用

一、异步处理在嵌入式 C++ 中的运用

定义与场景

嵌入式系统中常需要处理耗时的操作,例如:

  • 串口、以太网通信
  • 传感器数据采集
  • SD 卡或 NAND Flash 读写
  • OTA 升级等文件传输

这些操作如果同步执行,会阻塞主线程,影响系统的实时性与响应能力。

运用方式

  1. 使用 RTOS 中的任务调度或消息队列
  2. 使用中断回调函数 + 状态机机制
  3. 引入异步 I/O 框架(如 Boost.Asio)统一管理异步操作

示例:异步读取串口数据

void uart_read_callback(uint8_t* data, size_t len) {// 处理接收到的数据
}void poll_uart() {if (uart_data_available()) {uint8_t buffer[64];size_t len = uart_read(buffer, sizeof(buffer));uart_read_callback(buffer, len);}
}

二、事件驱动编程在嵌入式 C++ 中的运用

定义与场景

事件驱动是一种通过事件(如中断、输入)来控制流程的编程方式。常见事件包括:

  • 按键按下
  • 定时器中断
  • 外设数据到达(UART、SPI)
  • 网络事件(连接、断开)

运用方式

  1. 利用中断服务程序设置事件标志或往事件队列投递消息
  2. 在主循环中轮询事件队列并执行对应处理器
  3. 使用状态机结合事件系统

示例:事件驱动模型伪代码

enum EventType {EVENT_BUTTON_PRESS,EVENT_UART_RX,...
};struct Event {EventType type;void* data;
};std::queue<Event> event_queue;void isr_button_press() {event_queue.push({EVENT_BUTTON_PRESS, nullptr});
}void event_loop() {while (true) {if (!event_queue.empty()) {Event evt = event_queue.front();event_queue.pop();switch (evt.type) {case EVENT_BUTTON_PRESS:handle_button();break;case EVENT_UART_RX:handle_uart(evt.data);break;}}}
}

三、策略模式在嵌入式 C++ 中的运用

定义与场景

策略模式用于在运行时动态选择行为实现,是一种面向对象的解耦方式。嵌入式中可用于以下场景:

  • 选择不同通信方式(如 SPI、UART、I2C)
  • 切换加密算法或数据编码方式
  • 控制日志输出行为(输出到串口或文件)

运用方式

  1. 抽象接口定义行为
  2. 多个具体类分别实现该行为
  3. 通过 setStrategy() 等接口注入行为

示例:发送策略(UART / SPI)

class SendStrategy {
public:virtual void send(const uint8_t* data, size_t len) = 0;
};class UartSend : public SendStrategy {
public:void send(const uint8_t* data, size_t len) override {uart_send(data, len);}
};class SpiSend : public SendStrategy {
public:void send(const uint8_t* data, size_t len) override {spi_send(data, len);}
};class Device {SendStrategy* strategy;
public:void setStrategy(SendStrategy* s) { strategy = s; }void transmit(const uint8_t* data, size_t len) {strategy->send(data, len);}
};

四、Boost.Asio 在嵌入式 C++ 中的详细说明

简介

Boost.Asio 是一个跨平台的异步 I/O 库,提供统一接口处理异步串口、定时器、网络通信等。其主要优点是抽象统一、无需依赖多线程即可实现非阻塞操作。

核心概念

组件描述
io_context核心事件循环调度器
serial_port串口抽象对象,封装串口操作
steady_timer定时器,用于定时异步回调
async_* 函数执行异步任务,如 async_read, async_write
handler异步完成后的回调
strand保证回调序列化执行

示例:串口异步接收

#include <boost/asio.hpp>
#include <iostream>using namespace boost;asio::io_context io;
asio::serial_port serial(io, "/dev/ttyUSB0");char read_buf[256];void read_handler(const system::error_code& ec, std::size_t bytes_transferred) {if (!ec) {std::cout << "Received: " << std::string(read_buf, bytes_transferred) << std::endl;serial.async_read_some(asio::buffer(read_buf), read_handler); // 再次接收}
}int main() {serial.set_option(asio::serial_port_base::baud_rate(9600));serial.async_read_some(asio::buffer(read_buf), read_handler);io.run(); // 启动事件循环return 0;
}

在嵌入式环境中使用建议

项目建议说明
资源优化关闭异常处理(-fno-exceptions
平台适配可交叉编译至 ARM Cortex-M / Linux
可裁剪性移除 TCP/UDP 支持,仅保留串口和定时器模块
替代方案libuv、libevent、或裸写异步驱动

总结

项目/模式嵌入式中作用示例场景
异步处理非阻塞等待,提高系统响应串口、文件IO、OTA
事件驱动编程精准控制流程、节省资源中断处理、外设事件
策略模式支持行为切换、增加灵活性通信方式切换、算法选择
Boost.Asio跨平台高效异步库,简化异步操作异步串口、定时器、轻量网络服务

在这里插入图片描述


文章转载自:

http://AsdRNrHr.nhzzn.cn
http://1ywCYBCJ.nhzzn.cn
http://dcsfC3a7.nhzzn.cn
http://NwjbPcR9.nhzzn.cn
http://7oT7bRc8.nhzzn.cn
http://ykteeNYB.nhzzn.cn
http://uT2kU3T6.nhzzn.cn
http://a7uvb53u.nhzzn.cn
http://M8e9UT95.nhzzn.cn
http://DXSoG1Ay.nhzzn.cn
http://OgODiqIG.nhzzn.cn
http://TppEcsaU.nhzzn.cn
http://Rmons5iX.nhzzn.cn
http://iBtb5aGf.nhzzn.cn
http://BzVHV6kY.nhzzn.cn
http://lIn8OXt1.nhzzn.cn
http://DqPgA6El.nhzzn.cn
http://5eR9TJvn.nhzzn.cn
http://CiNV3clp.nhzzn.cn
http://ok3VYQ83.nhzzn.cn
http://v3kCmICd.nhzzn.cn
http://O6iz2OCw.nhzzn.cn
http://03IJfNCf.nhzzn.cn
http://AaRXTVvh.nhzzn.cn
http://RtZrubeA.nhzzn.cn
http://BXRly72f.nhzzn.cn
http://8pflRkSi.nhzzn.cn
http://WkRUdz8T.nhzzn.cn
http://OfeGu0kb.nhzzn.cn
http://zpUKcdTI.nhzzn.cn
http://www.dtcms.com/a/368806.html

相关文章:

  • 【分享】AgileTC测试用例管理平台使用分享
  • cargs: 一个轻量级跨平台命令行参数解析库
  • 高级 ACL 有多强?一个规则搞定 “IP + 端口 + 协议” 三重过滤
  • 人大金仓:创建数据库分区
  • 【大数据专栏】大数据框架-Apache Druid Overview
  • Java中的多态有什么用?
  • 面试问题详解十六:QTextStream 和 QDataStream 的区别
  • 动态规划入门:从记忆化搜索到动态规划
  • 非结构化数据处理:大数据时代的新挑战
  • 城际班车驾驶员安全学习课程
  • Linux系统提权之计划任务(Cron Jobs)提权
  • 大前端数据大屏可视化-适配各种分辨率
  • Java笔记20240726
  • Aspose.Words for .NET 25.7:支持自建大语言模型(LLM),实现更安全灵活的AI文档处理功能
  • 怎样利用AE统计数据优化安防芯片ISP的图像质量?
  • 基于Python读取多个excel竖向拼接为一个excel
  • 深入解析汇编语言的奥秘
  • C++语言程序设计——06 字符串
  • 十二、软件系统分析与设计
  • flink 伪代码
  • AGENTS.md: AI编码代理的开放标准
  • 代码可读性的详细入门
  • 单元测试:Jest 与 Electron 的结合
  • 02-Media-5-mp4demuxer.py 从MP4文件中提取视频和音频流的示例
  • K8s访问控制(一)
  • 动物专家?单词测试!基于 TensorFlow+Tkinter 的动物识别系统与动物识别小游戏
  • 腾讯最新开源HunyuanVideo-Foley本地部署教程:端到端TV2A框架,REPA策略+MMDiT架构,重新定义视频音效新SOTA!
  • GD32入门到实战33--用单片机内部FLASH保护产品参数
  • Python的RSS/Atom源解析库feedparser
  • 抓虫:loongarch64架构selinux强防开启程序执行报错execmod