Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C++ socket epoll初识

C++ socket epoll初识

作者头像
SimpleAstronaut
发布于 2022-11-03 07:42:35
发布于 2022-11-03 07:42:35
98700
代码可运行
举报
文章被收录于专栏:LMC的摸鱼博客LMC的摸鱼博客
运行总次数:0
代码可运行

Post Views: 3

C++ socket epoll初识

1.为什么要使用epoll

就像下面所给出的代码一样,在简单的情况下S/C服务器只能同时处理一个客户端连接。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>

int main() {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in serv_addr;}
    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    serv_addr.sin_port = htons(8888);

    bind(sockfd, (sockaddr*)&serv_addr, sizeof(serv_addr));

    listen(sockfd, SOMAXCONN);

    struct sockaddr_in clnt_addr;
    socklen_t clnt_addr_len = sizeof(clnt_addr);
    bzero(&clnt_addr, sizeof(clnt_addr));

    int clnt_sockfd = accept(sockfd, (sockaddr*)&clnt_addr, &clnt_addr_len);

    printf("new client fd %d! IP: %s Port: %d\n", clnt_sockfd, inet_ntoa(clnt_addr.sin_addr), ntohs(clnt_addr.sin
_port));
    return 0;

}

在这个连接的生命周期里,绝大部分时间都是空闲的,活跃时间(发送数据和接收数据的时间)占比极少,这样独占一个服务器是严重的资源浪费。事实上所有的服务器都是高并发的,可以同时为成千上万个客户端提供服务,这一技术又被称为IO复用。

通常来说,实现处理tcp请求,为一个连接一个线程,在高并发的场景,这种多线程模型与Epoll相比就显得相形见绌了。epoll是linux2.6内核的一个新的系统调用,epoll在设计之初,就是为了替代select, poll线性复杂度的模型,epoll的时间复杂度为O(1), 也就意味着,epoll在高并发场景,随着文件描述符的增长,有良好的可扩展性。

linux

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/proc/sys/fs/epoll/max_user_watches

表示用户能注册到epoll实例中的最大文件描述符的数量限制。

2.epoll原理

2.1 I/O多路复用

输入输出(input/output)的对象可以是文件(file), 网络(socket),进程之间的管道(pipe)。在linux系统中,都用文件描述符(fd)来表示。

I/O 多路复用的本质,是通过一种机制(系统内核缓冲I/O数据),让单个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是读就绪或写就绪),能够通知程序进行相应的读写操作。

select、poll 和 epoll 都是 Linux API 提供的 IO 复用方式。 Linux中提供的epoll相关函数如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
  • epoll_create: 创建一个epoll实例,文件描述符
  • epoll_ctl: 将监听的文件描述符添加到epoll实例中,实例代码为将标准输入文件描述符添加到epoll中
  • epoll_wait: 等待epoll事件从epoll实例中发生, 并返回事件以及对应文件描述符l

2.2 Unix的IO模型

我们在进行编程开发的时候,经常会涉及到同步,异步,阻塞,非阻塞,IO多路复用等概念,这里简单总结一下。

Unix网络编程中的五种IO模型:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Blocking IO - 阻塞IO
NoneBlocking IO - 非阻塞IO
IO multiplexing - IO多路复用
signal driven IO - 信号驱动IO
asynchronous IO - 异步IO

对于一个network IO,它会涉及到两个系统对象:

  1. Application 调用这个IO的进程
  2. kernel 系统内核

那他们经历的两个交互过程是:

阶段1: wait for data 等待数据准备; 阶段2: copy data from kernel to user 将数据从内核拷贝到用户进程中。

之所以会有同步、异步、阻塞和非阻塞这几种说法就是根据程序在这两个阶段的处理方式不同而产生的。

2.3 事件

2.3.1 可读与可写

可读事件,当文件描述符关联的内核读缓冲区可读,则触发可读事件。 (可读:内核缓冲区非空,有数据可以读取)

可写事件,当文件描述符关联的内核写缓冲区可写,则触发可写事件。 (可写:内核缓冲区不满,有空闲空间可以写入)

2.3.2 通知机制

通知机制,就是当事件发生的时候,则主动通知。通知机制的反面,就是轮询机制。

结合以上三条,epoll的通俗解释是:

当文件描述符的内核缓冲区非空的时候,发出可读信号进行通知,当写缓冲区不满的时候,发出可写信号通知的机制。

2.3.3 epoll事件触发

epoll事件有两种模型,边沿触发:edge-triggered (ET), 水平触发:level-triggered (LT)

水平触发(LT)

  • socket接收缓冲区不为空 有数据可读 读事件一直触发
  • socket发送缓冲区不满 可以继续写入数据 写事件一直触发

边缘触发(ET)

  • socket的接收缓冲区状态变化时触发读事件,即空的接收缓冲区刚接收到数据时触发读事件
  • socket的发送缓冲区状态变化时触发写事件,即满的缓冲区刚空出空间时触发读事件

边沿触发仅触发一次,水平触发会一直触发。

3.epoll处理高并发

IO复用的基本思想是事件驱动,服务器同时保持多个客户端IO连接,当这个IO上有可读或可写事件发生时,表示这个IO对应的客户端在请求服务器的某项服务,此时服务器响应该服务。在Linux系统中,IO复用使用select, poll和epoll来实现。epoll改进了前两者,更加高效、性能更好,是目前几乎所有高并发服务器的基石。

epoll主要由三个系统调用组成:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//int epfd = epoll_create(1024);  //参数表示监听事件的大小,如超过内核会自动调整,已经被舍弃,无实际意义,传入一个大于0的数即可
int epfd = epoll_create1(0);       //参数是一个flag,一般设为0,详细参考man epoll

创建一个epoll文件描述符并返回,失败则返回-1。

epoll监听事件的描述符会放在一颗红黑树上,我们将要监听的IO口放入epoll红黑树中,就可以监听该IO上的事件。

3.1 epoll数据结构

epoll 的核心数据结构是:1个红黑树和1个链表。还有3个核心API。如下图所示:

3.1.1 就绪列表

就绪列表引用着就绪的socket,所以它应能够快速的插入数据。

程序可能随时调用epoll_ctl添加监视socket,也可能随时删除。当删除时,若该socket已经存放在就绪列表中,它也应该被移除。(事实上,每个epoll_item既是红黑树节点,也是链表节点,删除红黑树节点,自然删除了链表节点)

所以就绪列表应是一种能够快速插入和删除的数据结构。双向链表就是这样一种数据结构,epoll使用双向链表来实现就绪队列(对应上图的rdllist)。

3.1.2 索引结构

既然epoll将“维护监视队列”和“进程阻塞”分离,也意味着需要有个数据结构来保存监视的socket。至少要方便的添加和移除,还要便于搜索,以避免重复添加。红黑树是一种自平衡二叉查找树,搜索、插入和删除时间复杂度都是O(log(N)),效率较好。epoll 使用了红黑树作为索引结构。

Epoll在linux内核中源码主要为 eventpoll.c 和 eventpoll.h 主要位于fs/eventpoll.c 和 include/linux/eventpool.h, 具体可以参考linux3.16。

下述为部分关键数据结构摘要, 主要介绍epitem 红黑树节点 和eventpoll 关键入口数据结构,维护着链表头节点ready list header和红黑树根节点RB-Tree root。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*
 * Each file descriptor added to the eventpoll interface will
 * have an entry of this type linked to the "rbr" RB tree.
 * Avoid increasing the size of this struct, there can be many thousands
 * of these on a server and we do not want this to take another cache line.
 */
struct epitem {
    union {
        /* RB tree node links this structure to the eventpoll RB tree */
        struct rb_node rbn;
        /* Used to free the struct epitem */
        struct rcu_head rcu;
    };

    /* List header used to link this structure to the eventpoll ready list */
    struct list_head rdllink;

    /*
     * Works together "struct eventpoll"->ovflist in keeping the
     * single linked chain of items.
     */
    struct epitem *next;

    /* The file descriptor information this item refers to */
    struct epoll_filefd ffd;

    /* Number of active wait queue attached to poll operations */
    int nwait;

    /* List containing poll wait queues */
    struct list_head pwqlist;

    /* The "container" of this item */
    struct eventpoll *ep;

    /* List header used to link this item to the "struct file" items list */
    struct list_head fllink;

    /* wakeup_source used when EPOLLWAKEUP is set */
    struct wakeup_source __rcu *ws;

    /* The structure that describe the interested events and the source fd */
    struct epoll_event event;
};

/*
 * This structure is stored inside the "private_data" member of the file
 * structure and represents the main data structure for the eventpoll
 * interface.
 */
struct eventpoll {
    /* Protect the access to this structure */
    spinlock_t lock;

    /*
     * This mutex is used to ensure that files are not removed
     * while epoll is using them. This is held during the event
     * collection loop, the file cleanup path, the epoll file exit
     * code and the ctl operations.
     */
    struct mutex mtx;

    /* Wait queue used by sys_epoll_wait() */
    wait_queue_head_t wq;

    /* Wait queue used by file->poll() */
    wait_queue_head_t poll_wait;

    /* List of ready file descriptors */
    struct list_head rdllist;

    /* RB tree root used to store monitored fd structs */
    struct rb_root rbr;

    /*
     * This is a single linked list that chains all the "struct epitem" that
     * happened while transferring ready events to userspace w/out
     * holding ->lock.
     */
    struct epitem *ovflist;

    /* wakeup_source used when ep_scan_ready_list is running */
    struct wakeup_source *ws;

    /* The user that created the eventpoll descriptor */
    struct user_struct *user;

    struct file *file;

    /* used to optimize loop detection check */
    int visited;
    struct list_head visited_list_link;
};

epoll使用RB-Tree红黑树去监听并维护所有文件描述符,RB-Tree的根节点。

调用epoll_create时,内核除了帮我们在epoll文件系统里建了个file结点,在内核cache里建了个 红黑树 用于存储以后epoll_ctl传来的socket外,还会再建立一个list链表,用于存储准备就绪的事件.

当epoll_wait调用时,仅仅观察这个list链表里有没有数据即可。有数据就返回,没有数据就sleep,等到timeout时间到后即使链表没数据也返回。所以,epoll_wait非常高效。而且,通常情况下即使我们要监控百万计的句柄,大多一次也只返回很少量的准备就绪句柄而已,所以,epoll_wait仅需要从内核态copy少量的句柄到用户态而已。

3.2 监听IO事件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);    //添加事件到epoll
epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);    //修改epoll红黑树上的事件
epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, NULL);   //删除事件

其中sockfd表示我们要添加的IO文件描述符,ev是一个epoll_event结构体,其中的events表示事件,如EPOLLIN等,data是一个用户数据union:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 */
} __EPOLL_PACKED;

epoll默认采用LT触发模式,即水平触发,只要fd上有事件,就会一直通知内核。这样可以保证所有事件都得到处理、不容易丢失,但可能发生的大量重复通知也会影响epoll的性能。如使用ET模式,即边缘触法,fd从无事件到有事件的变化会通知内核一次,之后就不会再次通知内核。这种方式十分高效,可以大大提高支持的并发度,但程序逻辑必须一次性很好地处理该fd上的事件,编程比LT更繁琐。注意ET模式必须搭配非阻塞式socket使用。

我们可以随时使用epoll_wait获取有事件发生的fd:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int nfds = epoll_wait(epfd, events, maxevents, timeout);

其中events是一个epoll_event结构体数组,maxevents是可供返回的最大事件大小,一般是events的大小,timeout表示最大等待时间,设置为-1表示一直等待。

在创建了服务器socket fd后,将这个fd添加到epoll,只要这个fd上发生可读事件,表示有一个新的客户端连接。然后accept这个客户端并将客户端的socket fd添加到epoll,epoll会监听客户端socket fd是否有事件发生,如果发生则处理事件。

3.3 epoll API

3.3.1 epoll_creat
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 int epoll_create(int size)

内核会产生一个epoll 实例数据结构并返回一个文件描述符,这个特殊的描述符就是epoll实例的句柄,后面的两个接口都以它为中心(即epfd形参)。size参数表示所要监视文件描述符的最大值,不过在后来的Linux版本中已经被弃用(同时,size不要传0,会报invalid argument错误)

3.3.2 epoll_ctl
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)

将被监听的描述符添加到红黑树或从红黑树中删除或者对监听事件进行修改

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef union epoll_data {
void *ptr; /* 指向用户自定义数据 */
int fd; /* 注册的文件描述符 */
uint32_t u32; /* 32-bit integer */
uint64_t u64; /* 64-bit integer */
} epoll_data_t;
struct epoll_event {
uint32_t events; /* 描述epoll事件 */
epoll_data_t data; /* 见上面的结构体 */
};

对于需要监视的文件描述符集合,epoll_ctl对红黑树进行管理,红黑树中每个成员由描述符值和所要监控的文件描述符指向的文件表项的引用等组成。

op参数说明操作类型:

EPOLL_CTL_ADD:向interest list添加一个需要监视的描述符EPOLL_CTL_DEL:从interest list中删除一个描述符EPOLL_CTL_MOD:修改interest list中一个描述符struct epoll_event结构描述一个文件描述符的epoll行为。在使用epoll_wait函数返回处于ready状态的描述符列表时,

data域是唯一能给出描述符信息的字段,所以在调用epoll_ctl加入一个需要监测的描述符时,一定要在此域写入描述符相关信息events域是bit mask,描述一组epoll事件,在epoll_ctl调用中解释为:描述符所期望的epoll事件,可多选。常用的epoll事件描述如下:

EPOLLIN:描述符处于可读状态EPOLLOUT:描述符处于可写状态EPOLLET:将epoll event通知模式设置成edge triggeredEPOLLONESHOT:第一次进行通知,之后不再监测EPOLLHUP:本端描述符产生一个挂断事件,默认监测事件EPOLLRDHUP:对端描述符产生一个挂断事件EPOLLPRI:由带外数据触发EPOLLERR:描述符产生错误时触发,默认检测事件

3.3.3 epoll_wait
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

阻塞等待注册的事件发生,返回事件的数目,并将触发的事件写入events数组中。

events: 用来记录被触发的events,其大小应该和maxevents一致

maxevents: 返回的events的最大个数处于ready状态的那些文件描述符会被复制进ready list中,epoll_wait用于向用户进程返回ready list。

events和maxevents两个参数描述一个由用户分配的struct epoll event数组,调用返回时,内核将ready list复制到这个数组中,并将实际复制的个数作为返回值。

注意,如果ready list比maxevents长,则只能复制前maxevents个成员;反之,则能够完全复制ready list。

另外,struct epoll event结构中的events域在这里的解释是:

在被监测的文件描述符上实际发生的事件。

参数timeout描述在函数调用中阻塞时间上限,单位是ms:

timeout = -1表示调用将一直阻塞,直到有文件描述符进入ready状态或者捕获到信号才返回;timeout = 0用于非阻塞检测是否有描述符处于ready状态,不管结果怎么样,调用都立即返回;timeout > 0表示调用将最多持续timeout时间,如果期间有检测对象变为ready状态或者捕获到信号则返回,否则直到超时。epoll的两种触发方式

epoll监控多个文件描述符的I/O事件。epoll支持边缘触发(edge trigger,ET)或水平触发(level trigger,LT),通过epoll_wait等待I/O事件,如果当前没有可用的事件则阻塞调用线程。

select和poll只支持LT工作模式,epoll的默认的工作模式是LT模式。

参考文献

图文详解 epoll 原理【Redis,Netty,Nginx实现高性能IO的核心原理】epoll 详解 – 腾讯云开发者社区-腾讯云 (tencent.com)

深入理解 Epoll – 知乎 (zhihu.com)

day03-高并发还得用epoll | csblog

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月23日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
linux 下经典 IO 复用模型 -- epoll 的使用
epoll 是 linux 内核为处理大批量文件描述符而对 poll 进行的改进版本,是 linux 下多路复用 IO 接口 select/poll 的增强版本,显著提高了程序在大量并发连接中只有少量活跃的情况下的CPU利用率。 在获取事件时,它无需遍历整个被侦听描述符集,只要遍历被内核 IO 事件异步唤醒而加入 ready 队列的描述符集合就行了。 epoll 除了提供 select/poll 所提供的 IO 事件的电平触发,还提供了边沿触发,,这样做可以使得用户空间程序有可能缓存 IO 状态,减少 epoll_wait 或 epoll_pwait 的调用,提高程序效率。
用户3147702
2022/06/27
7340
linux 下经典 IO 复用模型 -- epoll 的使用
Linux下Socket编程(四)——epoll的使用简介
相比于select,epoll最大的好处在于它不会随着监听fd数目的增长而降低效率。因为在内核中的select实现中,它是采用轮询来处理的,轮询的fd数目越多,自然耗时越多。 并且,在linux/posix_types.h头文件有这样的声明: #define __FD_SETSIZE 1024 表示select最多同时监听1024个fd,当然,可以通过修改头文件再重编译内核来扩大这个数目,但这似乎并不治本。
用户2929716
2018/08/23
2.3K1
Linux下Socket编程(四)——epoll的使用简介
Epoll详解及源码分析
对于水平触发模式(LT):在1处,如果你不做任何操作,内核依旧会不断的通知进程文件描述符准备就绪。
bear_fish
2018/09/20
1.9K0
Epoll详解及源码分析
图文详解 epoll 原理【Redis,Netty,Nginx实现高性能IO的核心原理】epoll 详解
输入输出(input/output)的对象可以是文件(file), 网络(socket),进程之间的管道(pipe)。在linux系统中,都用文件描述符(fd)来表示。
一个会写诗的程序员
2021/03/24
11.7K1
图文详解 epoll 原理【Redis,Netty,Nginx实现高性能IO的核心原理】epoll 详解
Linux epoll 实现原理
epoll 是 Linux 平台下的一种特有的 IO 多路复用的实现方式,与传统的 select/poll 相比,epoll 在性能上有很大的提升。本文主要讲解 epoll 的实现原理。
恋喵大鲤鱼
2022/10/24
1.8K0
Linux epoll 实现原理
c++ 网络编程(八)TCP/IP LINUX-epoll/windows-IOCP下 socket opoll函数用法 优于select方法的epoll 以及windows下IOCP 解决多
原文链接:https://www.cnblogs.com/DOMLX/p/9622548.html
徐飞机
2018/09/30
2.3K0
一文读懂 Linux epoll 实现原理
如下的代码中,先用 epoll_create 创建一个 epoll 文件描述符 epfd,再通过 epoll_ctl 将需要监听的 socket 添加到 epfd 中,最后调用 epoll_wait 等待数据。
恋喵大鲤鱼
2024/05/24
1.4K0
一文读懂 Linux epoll 实现原理
【Linux】从零开始使用多路转接IO --- epoll
之前提过的多路转接方案select和poll 都有致命缺点:底层都是暴力的遍历,效率不高! 对此,诞生出了epoll这个更好的方案!
叫我龙翔
2024/11/06
880
【Linux】从零开始使用多路转接IO --- epoll
深入了解epoll模型 -- 开卷有益
上网一搜epoll,基本是这样的结果出来:《多路转接I/O – epoll模型》,万变不离这个标题。 但是呢,不变的事物,我们就更应该抓出其中的重点了。 多路、转接、I/O、模型。 别急,先记住这几个词,我比较喜欢你们看我文章的时候带着问题。
看、未来
2022/05/06
7390
深入了解epoll模型 -- 开卷有益
【Go 语言社区】epoll详解
什么是epoll epoll是什么?按照man手册的说法:是为处理大批量句柄而作了改进的poll。当然,这不是2.6内核才有的,它是在2.5.44内核中被引进的(epoll(4) is a new API introduced in Linux kernel 2.5.44),它几乎具备了之前所说的一切优点,被公认为Linux2.6下性能最好的多路I/O就绪通知方法。 epoll的相关系统调用 epoll只有epoll_create,epoll_ctl,epoll_wait 3个系统调用。 1. int ep
李海彬
2018/03/20
2.7K0
【Go 语言社区】epoll详解
从linux源码看epoll
在linux的高性能网络编程中,绕不开的就是epoll。和select、poll等系统调用相比,epoll在需要监视大量文件描述符并且其中只有少数活跃的时候,表现出无可比拟的优势。epoll能让内核记住所关注的描述符,并在对应的描述符事件就绪的时候,在epoll的就绪链表中添加这些就绪元素,并唤醒对应的epoll等待进程。 本文就是笔者在探究epoll源码过程中,对kernel将就绪描述符添加到epoll并唤醒对应进程的一次源码分析(基于linux-2.6.32内核版本)。由于篇幅所限,笔者聚焦于tcp协议下socket可读事件的源码分析。
无毁的湖光-Al
2019/03/12
5.3K0
从linux源码看epoll
温故Linux后端编程(六):深入了解epoll模型
有的朋友可能对select也不是很了解啊,我这里稍微科普一下:网络连接,服务器也是通过文件描述符来管理这些连接上来的客户端,既然是供连接的服务器,那就免不了要接收来自客户端的消息。那么多台客户端,消息那么的多,要是漏了一条两条重要消息,那也不要用TCP了,那怎么办?
看、未来
2021/09/18
6970
【Linux网络】多路转接:select、poll、epoll
在Linux中,常见的多路转接/复用有 select、poll 和 epoll 。
_小羊_
2025/03/11
2480
【Linux网络】多路转接:select、poll、epoll
epoll
io多路复用有很多种实现,自Linux 2.6内核正式引入epoll以来,epoll已经成为了目前实现高性能网络服务器端的必备技术。相比较select、poll而言,在查询、复制、监听数量上,epoll都有极大优势。
冰寒火
2023/03/07
8650
【在Linux世界中追寻伟大的One Piece】多路转接epoll
不同于select使用三个位图来表示三个fdset的方式,poll使用一个pollfd的指针实现。
枫叶丹
2024/11/13
1080
【在Linux世界中追寻伟大的One Piece】多路转接epoll
epoll()函数总结
http://www.cnblogs.com/Anker/archive/2013/08/17/3263780.html
bear_fish
2018/09/20
2K0
epoll()函数总结
epoll的使用实例
  在网络编程中通常需要处理很多个连接,可以用select和poll来处理多个连接。但是select都受进程能打开的最大文件描述符个数的限制。并且select和poll效率会随着监听fd的数目增多而下降。
xcywt
2022/05/09
8110
多路IO—POll函数,epoll服务器开发流程
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
莫浅子
2023/11/01
3320
多路IO—POll函数,epoll服务器开发流程
select、poll、epoll
I/O多路复用就是通过一种机制,可以同时监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。
_咯噔_
2022/03/15
1.3K0
epoll入门
epoll用到的所有函数都是在头文件sys/epoll.h中声明的,下面简要说明所用到的数据结构和函数: 所用到的数据结构 typedef union epoll_data { void *ptr; int fd; __uint32_t u32; __uint64_t u64; } epoll_data_t; struct epoll_event { __ui
李海彬
2018/03/22
8550
相关推荐
linux 下经典 IO 复用模型 -- epoll 的使用
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验