select,poll,epoll

什么是IO?什么是高效的IO?

read/recv

1.没有数据,就会阻塞住(等待缓冲区资源就绪)
2.有数据,read/recv拷贝完成后进行返回
IO = 等+数据拷贝

高效的IO:减少等待的比重

有哪些IO的方式?这么多的方式,有哪些是高效的?

阻塞式IO: 一直等待,没有数据就挂起。
非阻塞式IO:一直等待,如果有数据就接受,没有数据就做自己的事情,查询有没有数据到来。
信号驱动式IO:SIGNAL信号,如果有数据,信号提醒。回调的方式,你好了你来叫我。
多路转接/多路复用:
异步IO:进程将任务交给操作系统。


对比:
阻塞式IO,非阻塞式IO,信号驱动式IO效率上是没有差别的。整体上,非阻塞式IO,信号驱动式可以做其他事情。
信号驱动有没有等待呢?等待了。
阻塞式IO,非阻塞式IO,信号驱动式IO,多路转接/多路复用每个人都等了,都参与了IO过程——同步IO。异步IO并没有参与读取IO的过程。

阻塞式和非阻塞式IO的差别?
共同:都要数据拷贝
不同:等的方式不一样

select:IO = 等 + 拷贝

select只负责等待,可以一次等待多个fd,select本身没有数据拷贝的能力,拷贝要read,write来完成。

1.了解select基本概念和接口介绍

#include <sys/select.h>

int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);

参数解析:

int nfds:select要监视多个fd中值最大的fd+1

剩下的四个全部是输入输出型参数:

select关心的事件,只有三类:a.读 b.写 c.异常

fd_set *readfds, fd_set *writefds,fd_set *exceptfds:

fd_set:位图结构,用来表示文件描述符集合

fd_set *readfds:

输入:表示用户告诉内核,你要帮我关心一下,我给你的集合中的所有fd的读事件---哪些fd上的读事件你要关心。比特位的位置,表示fd的数值,比特位的内容,表示是否关心。

输出:内核告诉用户,你所关心的多个fd中,有哪些已经就绪了。比特位的位置,表示fd的数值,比特位的内容,表示是否就绪。

让用户和内核之间互相沟通,互相知晓对方要的和关心的。

struct timeval *timeout:等待方式

  • nullptr->阻塞式等待
  • struct timeval timeout={0,0};非阻塞
  • struct timeval timeout={5,0};5s以内阻塞式,超过5s,非阻塞返回一次

返回值

  • ret>0:有几个fd就绪了
  • ret==0:超时返回
  • ret<0:select调用失败

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);

select特点:

1.select能同时等待的文件fd是有上限的,除非重新改内核,否则无法解决。
2.必须借助第三方数组,来维护合法的fd
3.select的大部分参数是输入输出型的,调用select前要重新设置所有fd,调用之后,我们还要检查更新所有的fd,这带来的就是遍历的成本--用户
4.select为什么第一个参数是最大fd+1呢? 确定遍历范围-内核层面
5.select采用位图,用户->内核,内核->用户,来回的进行数据拷贝。拷贝成本的问题。

EPOLL

poll也是一种linux中的多路转接的方案。

1.select的fd有上限的问题。
2.每次调用都要重新设置关心的fd。

#include <poll.h>

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

struct pollfd *fds:结构体数组

 struct pollfd {
               int   fd;         /* file descriptor */
               short events;     /* requested events */请求事件
               short revents;    /* returned events */就绪事件
           };

输入看fd+events

输出时fd+revents

nfds_t nfds:数组长度

int timeout:时间单位毫秒

  • >0:在timeout以内阻塞,否则每隔一段时间返回
  • =0:非阻塞等待
  • <0:阻塞等待

返回值

  • ret>0:有几个fd就绪了
  • ret==0:超时返回
  • ret<0:poll调用失败

 EPOLL

1.快速的认识epoll的接口

#include <sys/epoll.h>

int epoll_create(int size);

创建一个epoll模型

用户->内核

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
op:增,删,改


内核->用户

int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);

struct epoll_event *events,int maxevents:输出型参数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值