select poll epoll

本文详细解析Unix文件描述符的概念、作用及其实现原理,包括如何通过文件描述符进行文件操作、继承机制以及如何利用select、poll和epoll进行高效的文件描述符监控。重点介绍了文件描述符在系统中的角色、文件描述符的继承与管理,以及三种监控机制的使用场景与优劣对比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文件描述符:

Unix所有的东西皆文件
 文件可能是一个网络连接,FIFO,管道终端,磁盘上的文件等,文件描述符是一个和打开的文件相关联的整数。
 个人理解:一个索引key,通过此key可以得到文件相关的全部信息

 

如上图所示,文件描述符在用户区0代表标准输入,1代表标准输出,2代表标准错误。系统文件表在内核区,每个文件描述符对应了不同的系统文件表记录,该记录记录了偏移地址了等很多属性。最后一级为内存索引节点,记录了真正的文件节点内容和锁等一些信息。

文件描述符可继承。继承关系如下图:

上图为fork之前打开文件描述符的继承关系。也就是说fork之前打开的文件描述符都会被继承。系统文件表中记录着次数,每次删除,只有次数减为0时,才这阵被删除系统文件表中的记录。

下图为fork之后打开的文件描述符的继承关系:

可以看到0,1,2是一直呗继承的。也就是说标准输入标准输出标准错误一直继承。

select:

先看一下select的几个函数:

函数的一些说明:

nfds:文件描述符范围
    例如有两个文件描述符:一个是100,一个1000,那么nfds就得设为1001
readfds:读变化是否可读状态监控描述符
writefds:写变化是否可写状态监控描述符
execptfds:异常状态监控描述符
timeout:超时时间。设置成NULL阻塞知道有状态变化,设置成0表示立即返回不管有没有变化。

poll:

 

函数的一些说明:

fds:pollfd集合
nfds:pollfd集合大小
Timeout:超时时间  -1阻塞 0直接返回 其他正整数表示超时时间
pollfd说明:
fd :文件描述符
events:监测的事件
revents :实际发生的事件

 

epoll:

三个函数:
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); //等待事件发生
参数说明:
epfd:epoll_create 返回值
op:操作类型
EPOLL_CTL_ADD:注册新的fd到epfd中;
EPOLL_CTL_MOD:修改已经注册的fd的监听事件;
EPOLL_CTL_DEL:从epfd中删除一个fd;

epoll_event:
 struct epoll_event {
  _uint32_t events; /* Epoll events */
  epoll_data_t data; /* User data variable *
 };
 typedef union epoll_data {
  void *ptr;
  int fd;
  __uint32_t u32;
  __uint64_t u64;
 } epoll_data_t;

原理:

select:

poll:

poll跟select差不多,核心机制一样,只是函数形式不太一样。Poll没有文件描述符大小限制,不需要从0开始遍历,只遍历需要的
两者共有的缺点:
1.每次调用时要重复地从用户态读入参数。
2.每次调用时要重复地扫描文件描述符。
3.每次在调用开始时,要把当前进程放入各个文件描述符的等待队列。在调用结束后,又把进程从各个等待队列中删除。

 

epoll:

epoll的高效就在于,当我们调用epoll_ctl往里塞入百万个句柄时,epoll_wait仍然可以飞快的返回,并有效的将发生事件的句柄给我们用户。这是由于我们在调用epoll_create时,内核除了帮我们在epoll文件系统里建了个file结点,在内核cache里建了个红黑树用于存储以后epoll_ctl传来的socket外,还会再建立一个list链表,用于存储准备就绪的事件,当epoll_wait调用时,仅仅观察这个list链表里有没有数据即可。有数据就返回,没有数据就sleep,等到timeout时间到后即使链表没数据也返回。所以,epoll_wait非常高效

 

转载于:https://my.oschina.net/hejiula/blog/132436

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值