1.5 阻塞与非阻塞I/O

news2025/1/11 22:36:06

文章目录

  • 1、阻塞I/O
  • 2、非阻塞I/O
  • 3、异步I/O
  • 4、同步I/O
  • 5、epoll原理函数
    • 5.1、int epoll_create(int size)
    • 5.2、int epoll_ctl(int epfd,int op,int fd,struct epoll_event* event)
    • 5.3、int epoll_wait(int epfd,struct epoll_event* events,int maxevents,int timeout)
    • 5.4、内核向双向链表增加节点
  • 6、Linux命令

1、阻塞I/O

在这里插入图片描述

阻塞和非阻塞主要是指这个函数,是否会导致我们这个进程进入sleep休眠。
阻塞:这种函数,会导致进程进入休眠,在等待一个动作发生才会继续走下去,这种阻塞不好,效率很低

2、非阻塞I/O

在这里插入图片描述

不会卡住,充分利用CPU时间片,不断的调用accept和recvfrom函数来查看有没有数据到来,通过标记来进行判断,如果数据到来,那么就会卡着,将内核缓存区的数据拷贝到用户缓存区。

3、异步I/O

在这里插入图片描述

调用一个异步I/O函数,要给这个函数指定一个缓存区,还需要一个回调函数,其他事情交给操作系统,调用完一个异步I/O函数会立即返回,操作系统会判断数据是否到来,来了就会将数据拷贝到缓存区中,调用指定回调函数来通知你。

和非阻塞的差别:需要不停的调用I/O函数,如果数据来就会卡在I/O函数这,就会将数据从内核缓存区复制到用户缓存区,异步I/O不需要不停的调用,只需要调用一次,然后可以去执行其他事情,通过内核检查数据是否到来,在整个过程中没有卡顿

4、同步I/O

在这里插入图片描述

1、select先判断数据有没有,没数据卡在那里,有数据返回之后,用recvfrom去读取数据(还是会卡一下,取数据的时候,将内核缓存区拷贝到用户缓存区),更麻烦,需要调用两个函数才能拿到数据,所谓I/O复用,就是我可以同步等待多个socket的数据,任意一个socket上面有数据了我就去recvfrom去读

5、epoll原理函数

在这里插入图片描述

5.1、int epoll_create(int size)

1、int epoll_create(int size);
参数:
    size 创建的红黑树的监听数据节点(数目最大有多大,从Linux 2.6.8开始,max_size参数将被忽略,但必须大于零。)
返回值:
    成功 指向新创建的红黑树的根节点fd
    失败 -1 errno
作用:创建一颗空红黑树和一个双向空链表


流程:
1、开辟了一块eventpoll结构类型的内存
	结构中成员rbr指向,一颗红黑树的根节点
	结构中成员rdlist指向,双向链表的头指针

5.2、int epoll_ctl(int epfd,int op,int fd,struct epoll_event* event)

2int epoll_ctl(int epfd,int op,int fd,struct epoll_event* event);
参数:
    epfd: epoll_create 函数的返回值
    op: 对该监听的红黑树操作
        EPOLL_CTL_ADD   添加fd到 监听红黑树
        EPOLL_CTL_MOD   修改fd在监听红黑树上的监听事件
        EPOLL_CTL_DEL   将一个fd从监听红黑树上摘下(取消监听)
    fd:待监听的fd文件描述符
    event:结构体的地址
        struct epoll_event {
            uint32_t     events;      
            // EPOLLIN / EPOLLOUT / EPOLLERR
            epoll_data_t data;    
            // fd 对应监听事件的fd
            // void* ptr
            // u32
            // u64
        };
        typedef union epoll_data {
                void        *ptr;
                int          fd;
                uint32_t     u32;
                uint64_t     u64;
        } epoll_data_t;
返回值:
    成功 0
    失败 -1 errno
作用:把一个socket以及这个socket相关的事件添加到epoll对象描述符中,目的通过epoll来监听这个socket,有感兴趣的事件来了通知我们


流程:
1、EPOLL_CTL_ADD   添加
生成红黑树的节点,epitem结构体,将socket保存到节点中、作为红黑树的key,添加的事件也保存进去
	成员:rbn结构体包含三个指针,左、右、父节点的指针
	成员:rblist结构体包含:指向前一个元素,后元素的指针

2、EPOLL_CTL_DEL  删除
a)通过socket到红黑树中进行查找,
b)有就把这个节点删除

3、EPOLL_CTL_DEL  修改
a)通过socket到红黑树中进行查找
b)找到红黑树节点修改红黑树事件

5.3、int epoll_wait(int epfd,struct epoll_event* events,int maxevents,int timeout)

int epoll_wait(int epfd,struct epoll_event* events,int maxevents,int timeout);
参数:
    epfd:epoll_create 函数返回值 epfd
    events:传出参数【数组】,满足监听条件的
    maxevents:数组 元素的总个数1024
    timeout:毫秒
        -1 阻塞
        0 不阻塞
        >0  超时事件(毫秒)
返回值:
    >0 满足监听的总个数,可以用作循环上限
    0 没有fd满足条件
    -1 errno
作用:阻塞一小段时间,等待事件发生,返回事件集合,也就是获取内核的事件通知(遍历双向链表,把双向链表数据拷贝出去,拷贝完毕,移除)

5.4、内核向双向链表增加节点

总结:红黑树的节点是通过EPOLL_CTL_ADD添加进去的。
一般用四种情况,操作系统会把节点添加到红黑树上:
1、客户端完成三次握手,服务端要accept()
2、客户端关闭连接时候,服务器调用close()
3、到客户端发送数据,服务器调用read()
4、当可以发送数据时,服务器调用write()

6、Linux命令

# 查看有哪些进程监听80端口
lsof -i:80 

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

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

相关文章

【Linux 线程介绍】

Linux 线程线程一定越多越好吗?线程的实现方式:API:pthread_exit函数演示获取线程的返回值多线程的不安全性查看进程中的线程数进程:一个正在运行的程序 ,资源分配的基本单位 线程:进程内部的一条执行序列(…

接口自动化测试

接口自动化测试1.基础知识1.接口测试原理2.接口测试点及用例设计方法3.接口测试返回值的处理4.接口测试要点5.常见HTTP状态码6.HTTP基础知识7.接口自动化测试工具2.抓包工具1.chrom抓包2.Fiddle抓包(PC端,手机端)1.原理2.下载安装3. 认识界面…

HIbernate多表学习

一,表与表之间关系: 1.一对多:多的表用一个外键存一的表的主键id。 2.多对多:新建第三张表,两个外键分别存两个多的表的主键id。 3.一对一 二,Hibernate一对多练习: 一对多映射配置&#…

国际通用回收标准-GRS、RCS的答疑

【国际通用回收标准-GRS、RCS的答疑】 GRS & RCS 国际通用回收标准 GRS和 RCS是目前现行国际公认的回收材料标准。许多国际知名品牌如 ADDIDAS、3M、PUMA、H&M、NIKE等都是此标准的会员。GRS与 RCS最早开始于纺织产业,用以证明其产品或原料含有一定的回收材…

yolov5剪枝实战4: 正常训练和稀疏化训练

1. 准备自己的数据集 1.1 下载项目文件 准备好备注的数据集进行训练,我这里给出了标注好的足球的数据集。从百度网盘下载到项目目录下并解压,网盘地址见文末 VOCdevkit_ball.ziptestfiles.zipprepare_data.py1.2 解压建立或自行建立数据集 使用PASCAL VOC数据集的目录结构,…

怎么批量把图片转文字?教你几招轻松完成

工作中我们经常要与图片、文字打交道,特别是做资料收集的小伙伴,当收到图片资料的时候,就需要将其输出为文字进行保存,如果是单张的时候我们还可以使用手机或者微信直接拍照识别转,但是图片不止一张的时候,…

nvcc编译器之GPU代码编译(chapter 5)

目录 5. GPU编译 5.1 GPU多代架构 5.2 GPU特性列表 5.3 应用兼容性 5.4 虚拟架构 5.5 虚拟架构特性列表 5.6 兼容性补全机制 5.7 nvcc示例 5. GPU编译 本章描述了由nvcc与CUDA驱动协同维护的GPU编译模型。本文介绍了一些技术部分,并在最后给出了具体的示例…

100家!第一批5G应用解决方案供应商推荐名录

近日,5G应用产业方阵(5G AIA)在“2022年中国5G发展大会5G应用产业发展论坛”发布了“5G应用解决方案供应商推荐名录(第一批)”入库名单,旨在强化5G应用供需对接,推动5G应用解决方案成熟&#xf…

RDD缓存机制及持久化技术

文章目录RDD缓存RDD缓存API介绍RDD缓存代码演示示例RDD缓存执行原理RDD CheckPointCheckPoint代码演示示例CheckPoint与Cache对比RDD缓存 RDD之间进行Transformation计算,当执行开启之后,就会有新的RDD生成,而之前老的RDD就会消失&#xff0…

js逆向基础篇-某音乐网站-xx音乐

提示!本文章仅供学习交流,严禁用于任何商业和非法用途,如有侵权,可联系本文作者删除! 网站链接:aHR0cHM6Ly9tdXNpYy4xNjMuY29tLyMvc2VhcmNoL20vP3M9JUU1JUE0JUE5JUU0JUI4JThCJnR5cGU9MQ== 案例分析: 搜索歌曲名称,找到列表接口,如上图能看到列表数据的,之后看下传参,…

249 h221 最大岛屿面积

方式1 错误的动态规划 递归公式为 if (matrix[i][j]‘1’&&matrix[i-1][j-1]‘1’){ int edge(int) Math.pow(dp[i][j],0.5); // 边长 int addCount addCount(matrix, i, j, edge); dp[i][j]dp[i-1][j-1]addCount; maxMath.max(max,dp[i][j]); } 只根据 dp[i-1][j-1]…

Dev C++开发环境的配置及使用

标题Dev C开发环境的配置及使用 本文引用自作者编写的下述图书; 本文允许以个人学习、教学等目的引用、讲授或转载,但需要注明原作者"海洋饼干叔 叔";本文不允许以纸质及电子出版为目的进行抄摘或改编。 1.《Python编程基础及应用》&#xff0…

免费题库接口

免费题库接口 本平台优点: 多题库查题、独立后台、响应速度快、全网平台可查、功能最全! 1.想要给自己的公众号获得查题接口,只需要两步! 2.题库: 查题校园题库:查题校园题库后台(点击跳转&a…

[SUCTF 2019]Pythonginx

源码: app.route(/getUrl, methods[GET, POST]) def getUrl():url request.args.get("url")host parse.urlparse(url).hostnameif host suctf.cc:return "我扌 your problem? 111"parts list(urlsplit(url))host parts[1]if host suctf…

[论文评析]Densely Connected Convolutional Networks,CVPR,2017

Densely Connected Convolutional Networks, 文章信息背景与动机DenseNetDense blockDenseNetDenseNet的集中经典配置总结文章信息 题目:Densely Connected Convolutional Networks, 发表:CVPR,2017 作者:Gao Huang, …

【TWVRP】遗传算法求解带时间窗的含充电站车辆路径规划问题【含Matlab源码 1177期】

⛄一、VRP简介 1 VRP基本原理 车辆路径规划问题(Vehicle Routing Problem,VRP)是运筹学里重要的研究问题之一。VRP关注有一个供货商与K个销售点的路径规划的情况,可以简述为:对一系列发货点和收货点,组织调用一定的车辆&#xff…

【密码学篇】虚拟专用网技术原理与应用(商密)

【密码学篇】虚拟专用网技术原理与应用(商密) VPN技术不是洪水猛兽,其普遍应用于网络通信安全和网络接入控制,可通过服务器、硬件、软件等多种方式实现。—【蘇小沐】 文章目录【密码学篇】虚拟专用网技术原理与应用(…

JAVA多线程并发(一):线程的创建

JAVA多线程并发——创建线程 第一章:线程的创建与实现 文章目录JAVA多线程并发——创建线程一、继承Thread类二、实现runnable接口三、简单匿名内部类写法四、实现Callable接口五、线程池一、继承Thread类 代码示例: public class ExtendThread {publ…

SPARKSQL3.0-Unresolved[Parsed]阶段源码剖析

一、前言 上两节介绍了Antlr4的简单使用以及spark中如何构建SessionState,如果没有看过建议先了解上两节的使用,否则看本节会比较吃力 [SPARKSQL3.0-Antlr4由浅入深&SparkSQL语法解析] [SPARKSQL3.0-SessionState构建源码剖析] 那么在Unresolved…

MySql查询的生命周期和性能优化思路

目录 前言 1. 为什么查询性能差 2. 一次查询的生命周期 2.1 客户端与服务端通信 2.2 查询缓存 2.3 解析器 2.4 预处理器 2.5 优化器 2.6 查询引擎 2.7 存储引擎 3. 查询性能优化的思路 4.总结 前言 一说到mysql的查询性能优化,相信很多人能说出来很多的技…