第13章 网络 Page724 asio定时器

 程序代码:

11行,声明一个ios对象

13行,使用ios对象作为参数声明一个定时器,此时,定时器和ios完成了关联,后面定时器如果有任务的话,就可以将任务交给ios

16行,为定时器设置一个定时任务,13行,定时器已经和ios已经了关联,定时器就可以将定时器交给ios,定时工作由操作系统完成,所以这一行实际上,是将任务添加到io_service身上,因为这个定时任务,是由操作系统完成的。将任务添加到io_service身上,并不需要ios“转”起来

23~33行,使用定时器的async_wait()方法,为定时器设置一个回调动作(函数指针,函数对象,Lambda表达式,std::function对象都可以),当定时器的定时任务由ios完成以后(操作系统完成),操作系统则“吐”出一个事件给ios,告诉ios,定时任务完成了,你可以发起回调动作了, 如果ios空闲,并且ios的run()方法正在被调用,则ios处理此事件,发起回调动作,就是本例中Lamabda表达式。

37行,启动io_service服务,定时器定时任务由ios交给操作系统完成后,操作系统回馈给ios一个事件,通知ios任务已经完成,ios接收到此事件,便会发起回调动作。启动定时器的回调活动(async_wait()函数的参数)。若被注释掉,则定时任务完成后,不会启动回调活动。

综合起来,过程是这样的,13行,完成定时器与ios的关联,16行,为定时器设置一个任务,这个任务会被ios交给操作系统完成(这一步不需要ios“转”起来),操作系统完成任务完成后,回馈一个事件给ios, 通知ios,任务已经完成了,可以发起回调了,37行,如果ios的run()方法已经调用了,则,ios将发起回调动作,就是执行23行(设置一个回调动作)的Lambda表达式。

ios_service

ios_service(输入输出_服务),在asio新版中也叫io_context(输入输出_上下文)。更好的名称应是“io_engine(输入输出_引擎)”;run一词,不能简单地认为是有个小人在跑,而是要想到"运转"这个词。

本文中的程序第16行,就是往ios_service身上丢个定时任务

当我们调用io_service的run()方法,引擎的齿轮就转了起来,然后需要说三遍的重要事情来了:io_service对象的run()方法并非永久地转下去,它只是转到没有任务就立即停转(函数返回)

当io_service对象“转”起来(即run()方法正在执行),它就会去处理身上的事件当全部任务的全部事件都处理完成,该io_service对象就不再转动。后续要是又有新任务往它身上加,除非再次调用run(),否则任务都不会被执行,最终也许任务堆积成山。

任务来自何处?任务谁来完成?任务去往何处?

一、任务来自何处?

任务来自应用程序,比如我们写的代码:

timer_1.async_wait(...); 

timer_1在执行async_wait()方法时,创建了一个异步任务,并且将该任务交给io_service对象,即本例中的ios变量timer_1什么时候认识的ios对象的呢?请看它的构造过程:

boost::asio::system_timer timer_1(ios);

time_1是一个对象,它拥有一件有赖外部环境推动完成的任务这样的对象在asio中称为“I/O对象”。比如说“定时器”,之前在“异步、异步、异步”小节中演示了两种实现方法:一是当前应用程序的当前线程直接堵塞“睡”上一段时间,二是当前应用程序新开一个线程,让那个线程“睡上”上一段时间。尽管后者的表现效果是"异步",但与前者没有本质区别,因为在等待事情完成的期间,都百分百地耗费当前应用程序的一个线程。asio提供的timer,则将定时的工作交给操作系统或特定支撑框架,因为底层往往可以提供低成本的定时器实现。

小提示:定时器和“I/O”有关系吗?

可以这样理解,我们交个操作系统一个时长,经过该时长后,操作系统回馈一个信号以示“定时到啦”,这一进一出不就是“I/O”?

二、任务谁来完成?

答:任务本例中为定时工作被io_service交给操作系统完成

三、任务去往何处?

答:任务完成后就结束使命了,但为了让上层应用程序知道任务完成了,io_service对象会触发一个事件。事件就是创建任务时指定的回调动作,比如本例中timer_1.async_wait(...)调用时入参所指定的lambda表达式。因此可以理解为任务走了,事件来了。当然,前提是有线程在调用该io_service对象的run()方法

现在,关于io_service的图示如图13-18所示

任务交给操作系统之后,线程就空闲了,可以去处理别的任务。而操作系统完成任务后将“吐”出事件给某个io_service对象,此时如果有一个线程正好在运行该io_service对象的run()方法,并且它空闲(没有在处理之前的事件),它就有机会接收并处理该事件。如果这样的线程有多个,asio保障只会有一个线程接收并处理同一个事件。如果没有任何这样的线程,新事件就会无人受理。

程序的调试

若我们在第25行打一个断点,则会发现,调试启动以后,程序并不会立即停在第25行,而是在定时器任务完成之后,触发回调活动,程序才会停在第25行,这充分说明,回调活动是异步执行的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/682442.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【日常聊聊】新年新征程:迎接学习的挑战

🍎个人博客:个人主页 🏆个人专栏:日常聊聊 ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 结语 我的其他博客 前言 随着新的一年的到来,程序员们站在了全新的起点。这是一个充满机遇和挑战的时刻&#xff0…

【JavaEE】_HTTP请求与响应

目录 1. HTTP协议 1.1 HTTP简介 1.2 Fiddler 2. HTTP请求 2.1 首行 2.2 请求头(header) 2.3 空行 2.4 正文(body) 3. HTTP响应 3.1 首行 3.2 响应头(header) 3.3 空行 3.4 正文(bo…

51单片机编程基础(C语言):LED点阵屏

点阵屏介绍 类似于数码管,要用到肉眼视觉效应。扫描,才能把每一个LED都能选中,从而显示我们想要的图形,否则, 只能一次点亮一个LED, LED使用 51单片机点阵屏电路图: 实际连接顺序如下图&#…

爱快使用VPN

文章目录 一、VPN服务器1. 各种VPN比较2. PPTP服务端配置3. 创建登录账号4. 创建端口映射5. 设置动态域名 二、Windows客户端1. 连接配置2. 不能连接 Internet 配置 一、VPN服务器 1. 各种VPN比较 PPTPIPSECOpenVPN简介微软推出的VPN协议,占用资源少更高级的VPN协…

php基础学习之分支结构和循环结构(不细讲,来对比一下和两大常用高级编程语言(C++/Java)的细微区别以便记忆)

分支结构 常见分支结构 编程语言常见分支结构有: if语句if-else语句if-elseif-else语句switch语句 其中,除了if-elseif-else语句外,另外3中分支语句在php中和C/Java是一模一样的! 而if-elseif-else的唯一不同点就在,【…

Linux查看日志的几种方法总结

摘要 Linux系统中查看日志的命令确实多种多样,每个命令都有其特定的用途和优势。常用的命令有:tail、cat、tac、head、echo,grep、less、awk、sed。 下面我会详细解释这些命令在查看日志时的用法和特点: tail命令: ta…

机器学习:ROC曲线笔记

ROC曲线(Receiver Operating Characteristic Curve)是一种用于评估二分类模型性能的图形化工具,主要用于展示在不同阈值(Threshold)下模型的真阳性率(True Positive Rate,TPR)和假阳…

寒假作业:2024/2/14

作业1&#xff1a;编程实现二维数组的杨辉三角 代码&#xff1a; #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc, const char *argv[]) {int n;printf("please enter n:");scanf("%d",&n);int a…

Redis核心技术与实战【学习笔记】 - 31.番外篇:Redis客户端如何与服务器端交换命令和数据

简述 Redis 使用 RESP 协议&#xff08;Redis Serialzation Protocol&#xff09;协议定义了客户端和服务器端交互的命令、数据的编码格式。在 Redis 2.0 版本中&#xff0c;RESP 协议正式称为客户端和服务器端的标准通信协议。从 Redis 2.0 到 Redis 5.0 &#xff0c;RESP 协…

leetcode:55.跳跃游戏

1.解题思路&#xff1a;贪心算法看最大覆盖范围 2.模拟过程&#xff1a; 1.若数组长度等于1&#xff0c;直接返回True 2.循环遍历覆盖范围&#xff0c;选取最大的覆盖范围&#xff1b;若覆盖范围覆盖到了最后一个元素&#xff0c;直接返回true. 3.代码&#xff1a;(贪心无套…

ros自定义msg记录

文章目录 自定义msg1. 定义msg文件2. 修改 package.xml3. 修改 CMakeLists.txt4. message_publisher.py5. message_subscriber.py6. 运行 catkin build 测试 自定义msg ros 版本&#xff1a;kinetic 自定义test包的文件结构如下 |-- test | |-- CMakeLists.txt | |-- msg…

Hive3.1.2——企业级调优

前言 本篇文章主要整理hive-3.1.2版本的企业调优经验&#xff0c;有误请指出~ 一、性能评估和优化 1.1 Explain查询计划 使用explain命令可以分析查询计划&#xff0c;查看计划中的资源消耗情况&#xff0c;定位潜在的性能问题&#xff0c;并进行相应的优化。 explain执行计划…

收藏:关于块存储,文件存储和对象存储

在B站上看到”【IT老齐465】“这个系列相当不错&#xff0c;每次的视频15分钟左右&#xff0c;出了400多个了&#xff0c;今天偶然看到&#xff0c;地址是&#xff1a;【IT老齐465】块存储、文件存储、对象存储的关系与区别_哔哩哔哩_bilibili 精彩摘录如下&#xff1a;

【运维测试】移动测试自动化知识总结第1篇:移动端测试介绍(md文档已分享)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论移动测试相关知识。主要知识点包括&#xff1a;移动测试分类及android环境搭建&#xff0c;adb常用命令&#xff0c;appium环境搭建及使用&#xff0c;pytest框架学习&#xff0c;PO模式&#xff0c;数据驱动&#xff0…

python入门篇11-面向对象的基础使用

全文目录,一步到位 1.前言简介1.1 专栏传送门1.1.1 上文小总结1.1.2 上文传送门 2. python基础使用2.1 面向对象的基础使用2.1.1 创建类2.1.2 使用对象(定义成员变量)2.1.3 成员方法的定义与使用2.1.4 构造方法的使用2.1.5 常用魔术方法 2.2 面向对象思想核心2.2.1 面向对象_私…

PS | 15个快捷键演示

01 前言 工具&#xff1a;Adobe Photoshop 2021 安装&#xff1a;无 网上自查 02 快捷键表 Ctrl T自由变换[减小画笔大小]增加画笔大小Shift [降低画笔硬度Shift ]增加笔刷硬度D默认前景/背景颜色X切换前景/背景颜色Ctrl J通过复制新建图层Ctrl Shift J通过剪切新建图层Esc取…

使用 WPF + Chrome 内核实现高稳定性的在线客服系统复合应用程序

对于在线客服与营销系统&#xff0c;客服端指的是后台提供服务的客服或营销人员&#xff0c;他们使用客服程序在后台观察网站的被访情况&#xff0c;开展营销活动或提供客户服务。在本篇文章中&#xff0c;我将详细介绍如何通过 WPF Chrome 内核的方式实现复合客服端应用程序。…

位运算总结(Java)

目录 位运算概述 位运算符 位运算的优先级 位运算常见应用 1. 给定一个数n&#xff0c;判断其二进制表示中的第x位是0还是1 2. 将数n的二进制表示中的第x位修改为1 3. 将数n的二进制表示中的第x位修改为0 4. 位图 例题&#xff1a;判断字符是否唯一 5. 提取数n的二进制…

《区块链公链数据分析简易速速上手小册》第5章:高级数据分析技术(2024 最新版)

文章目录 5.1 跨链交易分析5.1.1 基础知识5.1.2 重点案例&#xff1a;分析以太坊到 BSC 的跨链交易理论步骤和工具准备Python 代码示例构思步骤1: 设置环境和获取合约信息步骤2: 分析以太坊上的锁定交易步骤3: 跟踪BSC上的铸币交易 结论 5.1.3 拓展案例 1&#xff1a;使用 Pyth…

OCP的operator——(2)OLM

文章目录 了解OperatorOperator Lifecycle Manager&#xff08;OLM&#xff09;OLM概念和资源OLM是什么OLM资源Cluster service version&#xff08;CSV&#xff09;Catalog source定制catalog source的image模板目录健康需求 SubscriptionInstall planOperator groupOperator …