Linux系统开发(1):IO多路复用

news2024/11/18 11:22:14

IO即输入输出,是主存和外部设备(磁盘驱动器、终端和网络)之间复制数据的过程。
在这里插入图片描述
IO过程

  1. 应用程序进程向操作系统发起IO调用请求;
  2. 操作系统将外部设备的数据加载到内核缓冲区;
  3. 操作系统将内核缓冲区的数据拷贝到进程缓冲区;
  4. 应用程序得到数据完成操作

IO模型
(1)阻塞IO:内核数据没有准备好,应用程序一直等待,一直到内核数据从内核拷贝到用户空间返回成功。
(2)非阻塞IO:内核数据没有准备好,返回错误到应用程序,应用程序再次轮询请求(应用程序不断进行系统调用)。
(3)IO多路复用:提供函数(select、poll、epoll)监控多个文件描述符的操作,一旦有任意内核数据就绪,函数返回可读状态,应用程序才进行系统调用。
(4)信号驱动IO:内核在数据就绪后通过信号通知应用程序,应用程序调用读取数据。
(5)异步IO:应用程序调用后立即返回,内核数据准备好后才拷贝到进程缓冲区,发送信号通知操作执行完毕。

select函数
select实现多路复用的方式是,将已连接的Socket都放入到一个文件描述符集合,然后调用select函数将文件描述符拷贝到内核里,让内核来检验是否有事件产生,检查的方式很粗暴,就是通过遍历文件描述符集合的方式,当检查到有事件产生后,将该Socket标记为可读或可写,接着再将整个文件描述符集合拷贝回用户态,然后用户态再通过遍历的方法找到可读或者可写的Socket,然后对其处理。

int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

timeval结构表示一个是时间值,表示等待的时间长度,tv_sec表示秒,tv_usec表示微秒。

struct timeval {
	time_t tv_sec;
	time_t tv_usec;
};

fd_set是一组文件句柄的集合。长度为16的位图数组(64位),一位表示一个文件描述符,共1024位。

typedef long int __fd_mask; // 位掩码数据类型,用于描述一组文件描述符

#define __NFDBITS	(8 * (int) sizeof (__fd_mask)) //8*8=64,(64位)

typedef struct
  {
#ifdef __USE_XOPEN
    __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];//__FD_SETSIZE宏定义为1024
# define __FDS_BITS(set) ((set)->fds_bits)
#else 
    __fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->__fds_bits)
#endif
  } fd_set;

FD_CLR从文件句柄组里删除一个文件句柄
FD_ISSET判断一个文件句柄是否在一个组内
FD_SET添加一个文件句柄到一个组,将socket对应的位置1,执行select后若socket可读或可写,对应的位置1否则置零。
FD_ZERO清空一个文件句柄组。

int socketId;
fd_set fdRead;
struct timeval timeout;

timeout.tv_sec = 5;
timeout.tv_usec = 0;

while(1) {
	FD_ZERO(&fdRead);
	FD_SET(socketId, &fdRead);//
	
	switch (select(socketId + 1, &fdRead, nullptr, nullptr, &timeout)) {
		case -1://出错
			cout << "error" << endl;
			break;
		case 0://超时
			cout << "timeout" << endl;
			break;
		default://判断套接字
			if (FD_ISSET(socketId)) {
				cout << "return Data" << endl;
				break;
			}
	}
}

poll函数

int poll(struct polled *ufds, unsigned int nfds, int timeout);

使用pollfd类型的结构来监控一组文件句柄,ufds是监控的文件句柄集合,nfds是监控的文件句柄数量,timeout指定等待的毫秒数。

struct pollfd {
	int fd;
	short events;
	short revents;
};

向poll函数传一个pollfd的数组,用于监控多个文件描述符,events是监控事件描述符的掩码,是用户感兴趣的事件;revents是文件描述符监控事件返回的掩码,是实际发生的事件。

int socketId;
struct pollfd pollfds;
int timeout;

timeout = 5000;
pollfds.fd = socketId;
pollfds.events = POLLIN | POLLPRI;//等同于select的读事件

while(1) { 
	switch (poll(&pollfds, 1, timeout)) {
		case -1://出错
			cout << "error" << endl;
			break;
		case 0://超时
			cout << "timeout" << endl;
			break;
		default://判断套接字
			if (FD_ISSET(socketId)) {
				cout << "return Data" << pollfds.revents << endl;
				break;
			}
	}
}

epoll函数
epoll_create:内核在epoll文件系统里建了个file结点,建立文件对象对应的红黑树,构建一个list链表。

epoll_ctl:传递socket到内核,在红黑树上构建节点、此外在内核中断处理程序注册对应的回调函数,当句柄发生中断,内核将句柄放到list链表中。

epoll_wait:观察list链表里是否有数据。有数据就返回,没有数据就sleep,等到timeout后返回。epoll_wait返回时仅需要从内核态copy少量的句柄(已准备就绪的)到用户态。

参考:
https://zhuanlan.zhihu.com/p/439770090
https://zhuanlan.zhihu.com/p/93609693
https://www.cnblogs.com/zhaoxinshanwei/p/3875739.html
《Linux系统开发详解》

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

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

相关文章

Linux:firewalld防火墙-小环境实验(3)

环境介绍 本章为全纯手打&#xff0c;无任何复制&#xff0c;如果哪句命令出错&#xff0c;请评论出来我会快速修改 需求 图中防火墙区域为网关服务器上分区 &#xff0c;在网站服务器上可以使用默认的或者别的 1&#xff09;首先关闭全部的服务器的防火墙&#xff0c;实现全…

【GWO-BP预测】基于灰狼算法优化BP神经网络回归预测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

YOLOv5项目实战(1)— 如何去训练模型

前言:Hello大家好,我是小哥谈。YOLOv5基础知识入门系列、YOLOv5源码中的参数超详细解析系列、YOLOv5入门实践系列、YOLOv5论文作图教程系列和YOLOv5算法改进系列学习完成之后,接着就进入YOLOv5项目实战系列了。🎉为了让大家能够牢固地掌握YOLOv5算法,本系列文章就通过一个…

高级二-十进制转换算法

输入二进制数字符串&#xff0c;按二进制数位权重计算&#xff0c;输出十进制数。 (本笔记适合熟悉二进制数和字符串的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程…

Excel多线程导入数据库

文章目录 Excel多线程导入数据库1. CountDownLatch2.多线程导入数据库 Excel多线程导入数据库 书接上文 Excel20w数据5s导入 1. CountDownLatch CountDownLatch 维护了一个计数器&#xff0c;初始值为指定的数量。当一个或多个线程调用 await() 方法时&#xff0c;它们会被阻…

Dapper中使用字符串作为动态参数查询时,结果不是预期的问题

1、如下图&#xff0c;c.industryId作为string类型当作参数传递&#xff0c;解析时会加单引号&#xff0c;即&#xff1a;”c.industryId“&#xff0c; 生成的查询语句就会变成 -- 这里把c.IndustryGroup 当成实际的值所以会查询不出数据 select b.Name,COUNT(c.Id) Num …

驱动作业10.23

现象 test.c #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include "head.h"in…

潮玩宇宙源码开发:开启全新的数字潮流时代

随着数字技术的飞速发展和人们对于娱乐需求的不断提升&#xff0c;潮玩宇宙源码开发逐渐成为了新的热门话题。潮玩宇宙是一个集潮流、艺术、科技于一体的数字娱乐新领域&#xff0c;通过将虚拟现实、增强现实等技术融入传统玩具设计中&#xff0c;为玩家们带来了全新的互动体验…

从零开始 Spring Cloud 15:多级缓存

从零开始 Spring Cloud 15&#xff1a;多级缓存 多级缓存架构 传统的缓存使用 Redis&#xff0c;大致架构如下&#xff1a; 这个架构存在一些问题&#xff1a; 请求要经过Tomcat处理&#xff0c;Tomcat的性能成为整个系统的瓶颈 Redis缓存失效时&#xff0c;会对数据库产生冲…

可在耳塞上记录大脑活动的3D打印传感器,未来或可用于诊断神经性疾病

原创 | 文 BFT机器人 加州大学圣地亚哥分校的研究人员探寻到一种方法&#xff0c;可以将日常耳塞变成可以记录大脑内部电活动的高科技设备。通过3D丝网打印的柔性传感器不仅能够检测来自大脑的电生理活动&#xff0c;还能收集人体的汗液乳酸——它是身体在运动和正常代谢活动过…

Risc0:使用Continunations来证明任意EVM交易

1. 引言 RISC Zero&#xff0c;设想了一个基于零知识证明的无限计算的未来。 2023年5月发布了RISC Zero zkVM v0.15版本&#xff0c;其中包含了一种重要feature&#xff1a; continuations。 在RISC Zero zkVM中&#xff0c;continuations为一种机制&#xff1a; 用于将大…

Apollo与TypeScript:强大类型检查在前端开发中的应用

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

如何制作.exe免安装绿色单文件程序,将源代码打包成可独立运行的exe文件

环境: rustdesk编译文件和文件夹 文件程序制作工具 问题描述: 如何制作.exe免安装绿色单文件程序,将源代码打包成可独立运行的exe文件,像官网那种呢? 将下面编译好的rustdesk文件夹制作成一个.exe免安装绿色单文件程序,点击exe就可以运行 在github上找了半天也没有…

大模型的实践应用3-大模型的基础架构Transformer模型,掌握Transformer就掌握了大模型的灵魂骨架

大家好,我是微学AI,今天给大家介绍一下大模型的实践应用3-大模型的基础架构Transformer模型,掌握Transformer就掌握了大模型的灵魂骨架。Transformer是一种基于自注意力机制的深度学习模型,由Vaswani等人在2017年的论文《Attention is All You Need》中提出。它最初被设计用…

【Java集合类面试十一】、HashMap为什么用红黑树而不用B树?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;HashMap为什么用红黑树而…

第四章 路由基础

目录 4.1 路由器概述 4.1.1 路由器定义 4.1.2 路由器工作原理 4.1.3 路由表的生成方式 &#xff08;1&#xff09;直连路由 &#xff08;2&#xff09;静态路由 &#xff08;3&#xff09;动态路由 4.1.4 路由器的接口 &#xff08;1&#xff09;配置接口 &#xff0…

Java毕业设计 SpringBoot 美食推荐系统 美食分享系统

Java毕业设计 SpringBoot 美食推荐系统 美食分享系统 SpringBoot 美食推荐系统 功能介绍 首页 图片轮播 登录注册 美食信息 搜索 美食分享 美食教程 美食排行榜 个人中心 更新个人资料 我的分享 我的收藏 在线咨询 后台管理 登录 个人中心 修改密码 用户管理 美食信息管理 美…

Spring+spring mvc+mybatis整合的框架

Spring是一个轻量级的企业级应用开发框架&#xff0c;于2004年由Rod Johnson发布了1.0版本&#xff0c;经过多年的更新迭代&#xff0c;已经逐渐成为Java开源世界的第一框架&#xff0c;Spring框架号称Java EE应用的一站式解决方案&#xff0c;与各个优秀的MVC框架如SpringMVC、…

经典卷积神经网络 - VGG

使用块的网络 - VGG。 使用多个 3 3 3\times 3 33的要比使用少个 5 5 5\times 5 55的效果要好。 VGG全称是Visual Geometry Group&#xff0c;因为是由Oxford的Visual Geometry Group提出的。AlexNet问世之后&#xff0c;很多学者通过改进AlexNet的网络结构来提高自己的准确…

day03_pandas_demo

文章目录 pandas介绍为什么使用pandasDataFrameDataFrame属性DataFrame的索引修改行列的索引值重设索引值以某列设置新索引 MultiIndexSerias索引操作直接索引按名字索引按数值索引 赋值操作排序对内容排序按索引排序 DataFrame的运算算术运算逻辑运算逻辑运算符号 < > |…