网络编程:IO多路复用(select、poll、epoll)

  1. 创建文件描述符集合

  2. 将关注的文件描述符添加到集合

  3. 将文件描述符传递给内核,内核开始检测IO事件

  4. 内核返回到达事件的结果

select:

特点:

  1. 使用数组(位图)保存文件描述符集合,最多允许监测1024个文件描述符;

  2. 将集合表创建在应用层,存在应用层和内核层数据的反复拷贝;

  3. 事件到达时,内核返回整个集合表,应用层需要遍历;

  4. select只能工作在水平触发模式(低速模式),不能工作在边沿触发模式(高速模式);

  5. 创建文件描述符集合(位图(数组)--》1024)

fd_set fds;

FD_ZERO(&fds);

  1. 将要监测的文件描述符加入集合

FD_SET(fd, &fds);

  1. 将集合传递给内核开始监测IO事件,并且返回监测的结果

int select(int nfds, fd_set *readfds, fd_set *writefds,

fd_set *exceptfds, struct timeval *timeout);

功能:将文件描述符传递给内核开始监测IO事件,并返回监测到的结果

参数:

nfds:监测的文件描述符最大值+1

readfds:要监测的读事件的文件描述符集合

writefds:要监测的写事件的文件描述符集合

exceptfds:要监测的出错事件的文件描述符集合

timeout:超时时间

NULL :不设置超时时间:阻塞等到

返回值:

成功:实际到达的IO事件的个数

失败:-1

0 :设置超时事件,超时时间到没有事件到达

void FD_CLR(int fd, fd_set *set);

int FD_ISSET(int fd, fd_set *set);

void FD_SET(int fd, fd_set *set);

void FD_ZERO(fd_set *set);

cpp 复制代码
int sockfd = socket();
bind();
listen();
//sockfd-->rdfds
while (1)
{
    select(rdfds);
    if (FD_ISSET(sockfd))
    {
    int connfd = accept();
        //connfd --->rdfds
    }
    for (i = sockfd+1; i <= maxfd; ++i)
    {
        if (FD_ISSET(i))
        {
            recv();
            send();
        }
    }
}

poll:
特点:

  1. 使用链表保存文件描述符集合,允许监测的文件描述符没有上限限制;

  2. 创建的文件描述符集合在应用层,需要应用层和内核层的反复数据拷贝;

  3. 应用层对于返回的事件结果需要遍历查找;

  4. poll只能工作在水平触发模式(低速模式),无法工作在边沿触发模式(高速模式)。

epoll:

特点:

  1. 使用树形结构(红黑树)保存文件描述符集合,没有文件描述符上限限制,并且查找效率高;

  2. 文件描述符集合创建在内核层,避免了应用层和内核层的反复数据拷贝;

  3. 直接返回到达事件的文件描述符集合;

  4. epoll可以工作在水平触发模式(低速模式),也可以工作在边沿触发模式(高速模式);

1. 创建文件描述符集合

int epoll_create(int size);

功能:创建epoll的文件描述符集合

参数:

size :允许监测的文件描述符的个数

返回值:

成功:返回文件描述符句柄。

失败:-1

2. 添加文件描述符到集合

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

功能:对文件描述符集合中的文件描述符做操作

参数:

epfd:epoll创建的文件描述符集合

op:操作方法:

EPOLL_CTL_ADD :添加操作

EPOLL_CTL_MOD :修改操作

EPOLL_CTL_DEL :删除操作

fd :要操作的文件描述符

event:epoll事件结构体

typedef union epoll_data {

void *ptr;

int fd; //要监测的文件描述符

uint32_t u32;

uint64_t u64;

} epoll_data_t;

struct epoll_event {

uint32_t events; /* Epoll events */

epoll_data_t data; /* User data variable */

};

events:事件类型

EPOLLIN: 读事件

EPOLLOUT :写事件

返回值:

成功:0

失败:-1

3. 通知内核开始监测事件

int epoll_wait(int epfd, struct epoll_event *events,

int maxevents, int timeout);

功能:通知内核开始监测事件

参数:

epfd:监测的文件描述符句柄

events :保存epoll返回的到达事件的集合

maxevents:最多监测的事件个数

timeout:设置超时时间

-1 :不设置超时,一直阻塞等待

返回值:

成功:实际到达的事件的个数

失败:-1

0 :超时时间到达,却没有事件返回时

相关推荐
从琳开始9896 小时前
网络原理入门(二)------OSI七层模型?TCP/IP五层(四层)模型原来是这样的
java·网络·tcp/ip·java-ee·php
CodeYp20197 小时前
第14讲:mmap 实现文件 LRU 缓存
linux·lru·mmap
程序开发阿元7 小时前
一台 20G 的 VPS 被日志吃掉一半:我按这个顺序查了二十分钟
linux·ssh
AOI小白新手上路8 小时前
深度学习算力购置方案分析:本地 RTX 4090 服务器 vs 云端租赁
服务器·人工智能·深度学习
.冰块.8 小时前
流量大了自动加 Pod!K8s HPA 扩缩容与 ResourceQuota/LimitRange 资源管控实战
linux·云原生·容器·kubernetes·hpa·quota·limitrange
xiaoye-duck8 小时前
《C++ 项目:手写大模型接入 SDK》ChatGPT接口设计(下):流式响应实现和测试
网络·c++·语言模型·chatgpt
梦帮科技8 小时前
意识启发式量子隧穿退火算法用于全局优化 (CITA) 完整技术指南
网络·人工智能·算法·量子计算·模拟退火算法
千桐科技8 小时前
qKnow智能体构建平台专业版 v3.1.5 发布:扩容工作流编排调用能力,上线Text2SQL插件,拓宽数据类智能应用构建边界
服务器·数据库·oracle·qknow
承渊政道8 小时前
Linux网络学习【深入理解多路转接select、poll的代码改写】
linux·ubuntu·select·多路转接·poll
雪落漂泊8 小时前
Linux进程(四)概念:命令行参数和环境变量篇
linux·运维·服务器