首页/新闻资讯/正文详情

并发编程(c++)——5.事件驱动

发布时间:2026/9/26 19:35:17 来源:云帆数科 栏目:资讯中心
并发编程(c++)——5.事件驱动
在并发编程中除了池和流的方式外还存在一种基本形式就是事件驱动。事件驱动的思想是使用一个线程不断循环处理任务将任务分发给其他复用的线程这样就通过单线程处理大量任务。发展历程io密集任务可以使用多线程一个io使用一个线程。但是如果任务过多比如达到百万级此时线程数量也会达到百万级别此时系统支持不了会崩溃。或者说使用线程池但是线程数量也需要很大频繁的切换线程也会带来大量的开销。这里有一个前提是io任务的处理机制基本一致可以用一个函数处理大量任务。此时可以考虑一种方式使用少量线程完成大量io任务。使用一个死循环一个队列队列中存储io任务死循环中不断处理io,这样就可以通过单线程处理百万io。但是这样会有阻塞问题处理io会使cpu等待所以需要将请求io和处理io分离。这样cpu只处理请求io处理io交给其他线程处理能充分利用cpu资源。同时还有一个问题循环内部会查询io任务队里,但如果io队列里没有任务这个循环就没有意义此时cpu会空转浪费资源。所以需要一种机制当io队列为空时让cpu等待当有任务时再唤醒cpu继续处理任务。背景问题1.使用多线程处理io密集任务当线程数量过大带来系统支持线程数不足线程切换资源消耗大。2.cpu和io处理时间差大带来的阻塞问题。3.非阻塞循环带来cpu空转。解决方案1.循环使用一个死循环不断读取任务和将任务分配给处理器。解决多线程处理使用单线程实现。2.分离发起io请求后不等待io返回继续处理其他任务当io返回后再处理io返回结果。解决阻塞问题。3.监督循环内部监视任务当任务为空时让cpu等待当有任务时再唤醒cpu继续处理任务。解决cpu空转问题。实现将所有任务抽象为不同的数据和对应的处理方式这就带获得了各个组成部分。实现因素1.事件将类型和数据抽象为一个结构体这个结构体就是事件。2.任务队列将要处理的事件放入队列中循环从队列中获取事件处理事件。3.处理器队列将任务类型和处理方式抽象为一个map,key为任务类型value为处理方式,放置在一个队列中处理任务时搜索这个队列找到对应任务类型执行处理方式。4.注册将处理器注册到处理器队列中。5.循环死循环调度任务队列和处理器队列监督任务队列当任务队列为空时让cpu等待当有任务时再唤醒cpu继续处理任务。6.分发有任务时查找任务对应的处理器将数据输入处理器中处理数据。#includestring#includequeue#includemap#includevector#includefunctional#includemutexstructevent{inttype;std::string data;};// 事件驱动类用于处理事件驱动的程序classEventDrive{private:// 事件队列用于存储待处理的事件std::queueeventqueue_events;// 事件处理器映射表键为事件类型值为对应的事件处理函数列表std::mapint,std::vectorstd::functionvoid(constevent)map_event_handlers;// 互斥锁用于保证线程安全std::mutex mut;// 运行状态标志true表示正在运行false表示已停止boolis_running;public:// 注册处理器为特定类型的事件注册一个处理函数voidon(inttype,std::functionvoid(constevent)handler);// 循环处理事件持续从队列中取出事件并处理直到is_running为falsevoidrun();// 添加事件将新事件添加到事件队列中voidadd_event(inttype,std::string data);// 处理事件根据事件类型查找并执行对应的处理函数voidhandle_event(constevente);// 停止事件驱动voidstop();};// 注册事件voidEventDrive::on(inttype,std::functionvoid(constevent)handler){map_event_handlers[type].push_back(handler);}// 循环处理事件voidEventDrive::run(){is_runningtrue;while(is_running){if(queue_events.empty()){continue;}else{std::lock_guardstd::mutexlock(mut);event equeue_events.front();queue_events.pop();handle_event(e);}std::this_thread::sleep_for(std::chrono::milliseconds(1));}}// 添加事件voidEventDrive::add_event(inttype,std::string data){std::lock_guardstd::mutexlock(mut);event e;e.typetype;e.datadata;queue_events.push(e);}// 处理事件voidEventDrive::handle_event(constevente){autoitmap_event_handlers.find(e.type);if(it!map_event_handlers.end()){for(autohandler:it-second){handler(e);}}}// 停止事件驱动voidEventDrive::stop(){is_runningfalse;}使用1.注册将处理器以函数的方式注册到处理器队列中。2.分析线程循环将事件驱动的循环在主线程外部执行这样主线程用于输入任务。3.载入任务将任务以事件的方式载入任务队列中。#includeevent_drive.hpp#includeiostreamintmain(){EventDrive envent_drive;//注册事件envent_drive.on(1,[](constevente){std::couthandler 1,收到事件1e.datastd::endl;});envent_drive.on(2,[](constevente){std::couthandler 2,收到事件2e.datastd::endl;});envent_drive.on(1,[](constevente){std::couthandler 3,也收到事件1e.datastd::endl;});// 启动事件循环std::threadloop_thread([envent_drive](){envent_drive.run();});// 发送事件envent_drive.add_event(1,data 1);envent_drive.add_event(2,data 2);envent_drive.add_event(1,data 3);// 停止事件循环std::this_thread::sleep_for(std::chrono::milliseconds(100));envent_drive.stop();loop_thread.join();return0;}结果handler 1,收到事件1data 1 handler 3,也收到事件1data 1 handler 2,收到事件2data 2 handler 1,收到事件1data 3 handler 3,也收到事件1data 3总结使用事件驱动的方式将任务抽象为事件将处理方式抽象为处理器将任务和处理器注册到事件驱动中事件驱动循环处理任务。

相关推荐

6LoWPAN与JenNet-IP实战:构建低功耗物联网网络的完整指南
6LoWPAN与JenNet-IP实战:构建低功耗物联网网络的完整指南

1. 项目概述与6LoWPAN核心价值如果你正在为智能家居、工业传感器网络或者任何需要将一堆低功耗、资源受限的无线设备连入IP网络的项目而头疼,那么你很可能已经听说过6LoWPAN。简单来说,它就像是为IEEE 802.15.4这类“小个子”无线网络量身定做的“瘦身衣… · 2026/9/24 12:46:47

NXP多核处理器硬件资源静态分配实战:从U-Boot到设备树的配置详解
NXP多核处理器硬件资源静态分配实战:从U-Boot到设备树的配置详解

1. 项目概述与核心价值在工业物联网和嵌入式系统的深水区里摸爬滚打了十几年,我越来越深刻地体会到,硬件资源的精细化管理,尤其是多核处理器上的资源分配,从来都不是一个简单的“配置”问题,而是一个关乎系统确定性、可… · 2026/9/25 20:50:00

i.MX VPU硬件解码器配置与运行机制深度解析
i.MX VPU硬件解码器配置与运行机制深度解析

1. 项目概述与核心价值 在嵌入式多媒体应用开发中,视频解码的性能和稳定性往往是决定产品体验的关键。无论是智能座舱里的流媒体播放,还是工业相机里的实时分析,都需要一个高效、可靠的解码后端。NXP i.MX系列处理器内置的Video Processing U… · 2026/9/25 15:41:58

DeepSeek Harness 新手必装插件推荐:8 个提升开发效率的 DSH 插件
DeepSeek Harness 新手必装插件推荐:8 个提升开发效率的 DSH 插件

1. 为什么新手装完 DSH 第一件事是挑插件,而不是急着写代码刚接触 DeepSeek Harness(后面统一简称 DSH)的人,十有八九会犯同一个错误:装完本体,打开终端,看到那个朴素的命令行界面,然… · 2026/9/26 19:34:43

DSH新手必装:8个插件快速上手与避坑指南
DSH新手必装:8个插件快速上手与避坑指南

1. 为什么我劝新手从这 8 个 DSH 插件开始上手刚接触 DSH(DeepSeek Harness)的朋友,十有八九会卡在同一个地方:装好了本体,打开界面,然后盯着空荡荡的插件列表发呆,不知道下一步该干什么。我当初… · 2026/9/26 19:34:43

多相机同步精度怎么测:从曝光时刻到抖动统计的工程方法
多相机同步精度怎么测:从曝光时刻到抖动统计的工程方法

多相机系统的同步精度,指的是同一个物理事件在各路数据中出现时刻之间的差值。工程上真正被测的东西经常被搞错:很多人测的是"数据到达主机的时刻差",而不是"曝光发生的时刻差"。前者包含读出、封装、传输与驱动排队&… · 2026/9/26 19:34:37

OpenCode Harness 架构解析:智能体数据分析全流程实操指南
OpenCode Harness 架构解析:智能体数据分析全流程实操指南

1. 从 Harness 说起:为什么智能体需要一个“骨架”第一次接触 OpenCode 的 Harness 架构时,我脑子里冒出来的第一个念头是:这不就是给大模型装了一副骨架吗?后来用久了才发现,这个比喻只对了一半。Harness 更像是一套“… · 2026/9/26 19:34:37

当 AI 学会了“越狱”:从 Codex 绕过 Sudo 事件看智能体权限管理的边界——用 TaoToken 统一 Key 复现权限配置骨架
当 AI 学会了“越狱”:从 Codex 绕过 Sudo 事件看智能体权限管理的边界——用 TaoToken 统一 Key 复现权限配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 19:34:11

提升效率:利用工具自动生成 Git 提交注释——TaoToken 统一 Key 接入 IDE 插件与脚本的配置骨架
提升效率:利用工具自动生成 Git 提交注释——TaoToken 统一 Key 接入 IDE 插件与脚本的配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 19:34:11

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码