【网络编程】IO多路转接

IO多路转接

@(Linux)


1.基本概念

适合场景

多用于有大量链接,但同一时间活跃量较小

2.select

2.1基本流程

  • IO多路转接的第一种模型,服务器端能够同时监控多个客户端的套接字,当有事件发生时,进行相应的操作
  • 事件发生:创建新链接,读操作,写操作,异常处理
  • 文件描述符数组:用户自定义,用于存放套字
  • 内核位图:三种文件描述符集合,系统等待直到有文件描述符状态改变
    这里写图片描述

2.2函数原语

#include

2.3优缺点

  • 优点
    • 可以跨平台
  • 缺点
    • 描述符有上限 集合中有1024位
    • 数据每次都从用户态拷贝到内核态,自定义数组->集合
    • 轮询遍历数组,所以描述越多,效率越低
    • 重新添加,每次有事件就绪时,监控的文件描述符状态改变,数组重新添加到集合
    • 编码复杂度较高

3.poll

3.1基本流程

pollfd结构体,用于记录世界

3.2函数原语

struct pollfd {
    int fd; //文件描述符
    short events; //监控的集合
    short revents; //返回的集合
}

int poll(struct pollfd* fds, nfds_t nfds, int timeout);
fds 可以表示结构体列表,多个结构体

3.3优缺点

  • 优点
    • 在资源足够下,描述符无上限
    • 编码复杂度较低
  • 缺点
    • 态拷贝
    • 轮询遍历 描述符增加性能降低
    • 不可跨平台

4.epoll

4.1基本流程

建立一个文件描述符集合(监控队列),在内核态有一个就绪队列,有事件就绪时加入到就绪队列

struct epoll_event  事件结构体
fd/ptr

event_poll 红黑树–监控队列,双向链表–就绪列
事件触发回调—事件触发,回调函数知道是什么事件,红黑树搜索找到事件,插入双向链表;用户自定义数组,从链表中拷贝,操作

4.2函数原语

epoll_create
epoll_ctl(EPOLL_CTL_ADD) //添加到监控队列
epoll_wait()

int nfds epoll_wait(struct epoll_event[]) 等待监控, 就绪添加到自定义数组epoll_event
- LT模式 水平触发 :只要新事件满足就绪条件就会一直返回通知我们;一共10字节,每次接受2字节,通知5次
- ET模式 边缘触发 :只有每次新事件就绪的时候才会返回给我们通知;一共10字节,每次接受2字节,直到把缓存区数据读完,最后通知1次;若缓存区已读完,但对端的写端没有关闭,所以会一直阻塞;
- 一次将所有数据读取出来,否则不会再次提醒,直到下次新数据到了,才提醒;有可能造成recv阻塞,因此需要socket设置为非阻塞;
- 惊群效应: 多服务器,负载均衡

4.3优缺点

  • 优点
    • 描述符无上限
    • 事件回调,不会随着描述符的增加,性能下降;
    • 每个事件只需添加到内核态一次,不需要重复添加,效率高
    • 编码难道较小
    • 就绪事件直接交付发我们,直接遍历,不用多余的遍历;
  • 缺点
    • 不可跨平台
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章