网络编程: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 :超时时间到达,却没有事件返回时

相关推荐
AI日报派送佬4 小时前
2026年10月14日AI行业日报|Gemini 4 Argon正式发布;小模型跨设备传播风险引发安全热议
网络·人工智能·openai·谷歌·deepseek·anthropic·ai日报
鬼手点金5 小时前
nanoGPT/nanochat 能做出 DeepSeek/Qwen 这样的大模型吗?
服务器·前端·javascript·bug·openclaw
安易算力5 小时前
昇腾CANN算子开发与MindSpore部署调优实践:从Ascend C到模型推理全链路
网络·架构
贵州诚鑫致达科技有限公司5 小时前
Linux的yum源怎么重启?源不是服务
linux·运维·服务器
遇印记6 小时前
传输层,网络层
运维·服务器·网络·windows·学习
Elastic 中国社区官方博客7 小时前
一条 ES|QL 查询,涵盖365天的审计日志:在热数据和可搜索快照上执行相同的搜索
大数据·运维·服务器·elasticsearch·搜索引擎·全文检索
北京中科新远科技8 小时前
高速光模块上线验收实战:DOM、FEC、BER与端口计数器怎么一起看
服务器·网络·php
澜山奕秋9 小时前
RHCSA
linux·运维·服务器
pride.li9 小时前
第03章 Python 教程-基础语法:注释与变量
服务器·前端·后端·python·算法·计算机视觉