IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Linux--高级IO -> 正文阅读

[网络协议]Linux--高级IO

  • IO:输入输出-- 过程:等待IO就绪,进行数据拷贝

1. 四种典型IO方式

  • 典型IO:阻塞IO,非阻塞IO,信号驱动IO, 异步IO
  1. 阻塞IO:发起IO调用,若IO 未就绪(IO条件不具备),则一直等待
  2. 非阻塞IO:发起IO调用,若IO未就绪,则立即报错返回
  3. 信号驱动IO:自定义IO信号处理,等待IO就绪收到信号打断当前操作进行IO
  4. 异步IO:自定义IO信号处理,发起IO调用,调用立即返回,但让系统完成IO,完成后通过信号通知进程
    在这里插入图片描述
    在这里插入图片描述
  • 从阻塞IO异步IO是资源利用率以及效率提高的过程,也是流程复杂的过程。
  • 阻塞:为了完成某功能,发起一个调用,若完成功能条件不具备,则一直等待;
  • 非阻塞:发起一个调用,若完成功能条件不具备,则立即报错返回
  • 阻塞与非阻塞:通常用于描述某个接口发起调用后是否能够立即返回
  • 同步:一个功能完成后,才能进行下一个,若不能立即完成则一直等待;流程清晰简单,但是效率相较于异步较低。
  • 异步:发起一个调用,让别人完成具体功能,不用等待功能完成后才能继续推进。对资源利用率高,效率更高,但是流程较为复杂。
  • 同步与异步:通常用于描述功能的完成流程(外部体现就是功能是否是自己完成的)
  • 异步阻塞与非阻塞:区别在于进程是否等待系统完成任务
    · 异步阻塞:发起一个调用,让系统完成任务,任务不完成进程也一直等着
    · 异步非阻塞:发起一个调用,让系统完成任务,进程继续做自己的事情

2. IO多路转接

  • 也叫IO多路复用
  • 作用:针对大量描述符进行IO就绪事件监控,让进程仅仅针对已经就绪了IO事件的描述符进行IO操作,避免了进程对未就绪的描述符进行操作所带来的性能损失或者阻塞。
  • 实现:select、poll、epoll
  • IO就绪事件:可读、可写、异常

2.1 select模型

  • 针对大量描述符进行IO就绪事件监控

操作流程

  1. 定义指定IO事件的描述符集合,将需要监控指定事件的描述符添加到对应集合中
  2. 发起监控调用,将需要监控的事件描述符集合拷贝到内核,进行事件监控。若监控超时了都没有描述符就绪则返回;若有描述符就绪了指定监控的事件则返回。在监控调用返回前,都会将事件描述符集合中没有就绪事件的描述符移除掉,也就是说,调用返回后,集合中保留的只有就绪的描述符。
  3. 判断哪个描述符在哪个集合中,就知道哪个描述符就绪了什么事件,进而进行对应IO操作

接口认识:

  • 定义集合:fd_set rfds, wfds,efds;

  • 清空集合:void FD_ZERO(fd_set *set) ;

  • 将描述符添加到集合中:void FD_SET(int fd, fd_set *set);

  • 发起监控调用:int select(int nfds, fd_set * readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
    · nfds:所有集合中最大的描述符的值+1;
    · readfds/writefds/exceptfds:可读,可写,异常,不监控置空
    · timeout:监控超时等待时间 struct timeval{tv_usec, tv_sec}; 一直等待则置空,非阻塞则数据置0
    · 返回值:返回实际就绪的描述符个数;出错返回-1;超时返回0;

  • 调用返回后,判断哪个描述符还在集合中 ,确定哪个描述符就绪了什么事件
    · int FD_ISSET(int fd, fd_set *set);

  • 从指定集合中移除指定的描述符
    · void FD_CLR(int fd, fd_set *set);

      多路转接模型是针对一个或多个描述符进行IO就绪事件监控的功能
      	通常应用于tcp服务器端,针对大量套接字描述符进行监控,让程序能够仅仅针对就绪的描述符进行操作,进而提高处理效率
      	而udp服务端大多针对单个套接字进行操作
      	大多数情况也会用到多路转接模型,因为多路转接模型不但可以进行IO就绪事件监控,还可以进行超时控制
    

select特性总结

  1. 优点:跨平台移植性较好
  2. 缺点:
    • select所能监控的描述符有数量上限,上限取决于宏_FD_SETSIZE
    • select每次进行监控都要重新向集合中添加描述符(每次都会修改),且每次都要重新将集合拷贝到内核
    • select监控原理实在内核中进行轮训遍历,性能随着描述符的增多而下降。
      · 将集合中描述符遍历一遍看看有没有就绪的;
      · 有就直接移除未就绪返回,没有则挂起等待;
      · 有描述符就绪/超时后被唤醒,重新遍历一遍移除未就绪后返回。
    • select返回的是就绪集合,需要用户判断哪个描述符还在哪个集合中,才能确定哪个描述符就绪了哪个事件。

2.2 poll

  • 接口认识
    · int pll(struct pollfd *fds, nfds_t nfds, int timeout);
struct pollfd
{
	int fd; //要监控的描述符
	short events; //fd描述符要监控的事件
	short revents; //监控调用返回后,用于记录实际就绪的事件
};

· fds:描述符事件结构数组
· nfds:数组中有效节点个数;
· timeout:超时时间;
· 返回值:等于0表示超时;小于0表示出错;有就绪则大于0.

操作流程

  1. 定义事件结构体数组,为每个需要监控的描述符定义事件结构
  2. 发起监控调用,将数组中有效节点拷贝到内核进行监控,超时/就绪则调用返回,返回前将描述符实际就绪的事件记录到对应节点的revents成员中
  3. 调用返回后,遍历事件数组,通过每个节点的revents成员确定对应节点描述是否就绪了某个事件

优缺点:

  • 优点
    · poll能够监控的描述符数量没有上限限制;
    · 代码操作流程相较于select较为简单。
    -缺点
    · 跨平台移植性较差;
    · 监控原理依然是遍历轮询,性能会随着描述符增多而下降;
    · 监控返回后依然需要遍历事件结构数组确定描述符是否就绪。

2.3 epoll

  • Linux下最好用的多路转接模型

接口认识

  • int epoll_create(int size); – 在内核中创建epoll句柄;
    · size:监控的数量上限,Linux2.6之后被忽略,大于0即可
    · 返回值:成功返回描述符,失败返回-1
  • int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev);
    · epfd:epoll_create返回的epoll描述符;
    · op:EPOLL_CTL_ADD / EPOLL_CTL_DEL / EPOLL_CTL_MOD
    · fd:针对op类型所操作的监控描述符
    · ev:针对fd描述符所定义的事件结构体
struct epoll_event
{
	uint32_t events;//要监控的事件-- 监控返回后实际就绪事件
	//自定义信息,通常用于保存事件节点对应要监控的描述符
	epoll_data_t{void *ptr, int fd;}data;	
};

· 返回值:成功返回0;失败返回-1

  • int epoll_wait(int epfd, struct epoll_event *evs, int maxe, int to);
    · epfd:epoll描述符;
    · evs:epoll_event数组首地址,用于保存就绪的描述符对应事件结构
    · maxe:通常evs数组的节点个数-- 指定要获取的事件最大个数
    · to:超时时间-- 毫秒
    · 返回值:超时返回0;出错返回-1;有就绪返回就绪事件个数

操作流程

  1. 在内核中创建epoll句柄结构
  2. 向内核epoll句柄结构中添加要监控的描述符以及对应事件结构
  3. 传入一个事件结构数组,开始监控,监控是一个异步阻塞操作。
    · 告诉系统开始监控,而描述符的监控由系统完成
    · 系统为每个描述符的就绪事件做了一个事件回调函数,一旦某个描述符就绪了指定的事件,则会调用事件回调函数,将这个描述符对应的事件结构添加到就绪事件双向链表
    · epoll_wait接口每隔一段事件查看epoll句柄结构的rdllist- 就绪双向链表是否为空,就可以判断有没有描述符就绪,超时则直接返回,如果由就绪,则将就绪的事件结构信息拷贝到传入的数组中。
  4. 监控调用返回后,只需要遍历evs数组,逐个对节点中的描述符进行对应事件的处理即可

epoll的事件触发方式:

  • IO事件的就绪:
    · 可写:描述符的发送缓冲区中剩余空间大小大于低水位标记
    · 可读:描述符的接收缓冲区中数据大小大于低水位标记
    · 低水位标记:类似于一个基准值-- 默认1字节
  • IO就绪事件的触发方式:水平触发- 默认,边缘触发- epoll特有
    · 水平触发:
    可读:只要缓冲区中有数据就会触发可读事件
    可写:只要缓冲区中有剩余空间就会触发可写事件
    · 边缘触发:EPOLLET
    可读:只有新数据到来的时候才会触发可读事件
    可写:只有缓冲区从没有剩余空间变为有剩余才会触发可写事件
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    epoll优缺点
  • 缺点:跨平台移植性较差
  • 优点
    · 所能监控的描述符没有数量上限
    · 描述符以及事件结构只需要向内核拷贝一次
    · 监控原理采用异步阻塞没监控有系统完成,进程只需要判断就绪链表是否为NULL即可,性能不会随着描述符增多而下降
    · 直接返回的都是就绪的描述符对应事件结构,减少空遍历

2.4 多路转接模型

  • 适用于有大量描述符需要监控,但是同一时间只有少量活跃的场景
  • poll/select适用于单个描述符的超时控制
  • 单个描述符的临时控制这里不适用epoll
  • 在实际使用中,多路转接模型通常搭配线程池一起使用
    · 对大量描述符进行监控,就绪事件后则抛入线程池进行处理
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-09-05 11:23:21  更:2021-09-05 11:27:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年6日历 -2024/6/27 2:09:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码