2019.07 Linux IO模型总结

三种IO模型

在《Unix网络编程》一书中提到了五种IO模型,分别是:阻塞IO、非阻塞IO、多路复用IO、信号驱动IO以及异步IO,这里主要介绍前三种。

阻塞IO

当用户线程发出IO请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除阻塞。
Eg:read、write函数

非阻塞IO

当用户线程发起一个IO操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送read操作。一旦内核中的数据准备好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。
非阻塞IO在实际使用中,用户线程需要不断进行IO询问,会一直占用CPU,导致CPU占用率非常高,因此一般情况下很少使用。
Eg: 把一个文件描述符设置为非阻塞模式的方法
flags = fcntl(sockfd, F_GETFL, 0); //获取文件的flags值。
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); //设置成非阻塞模式;

IO多路复用

在用户线程中监控多个文件描述符,将多个IO阻塞复用到一个select/poll的阻塞上。

IO多路复用——select

函数原型:
int select(int maxfdp1,fd_set *readset,fd_set *writeset,fd_set *exceptset,const struct timeval *timeout);
返回值为就绪的文件描述符个数。
select有以下缺点:
1、每次调用select都需要在内核遍历传递进来的所有fd_set(读、写、异常文件描述符)
2、并且限制监控的fdset中文件描述符最大值为1024(由内核中的宏控制,不重新编译内核的前提下不可改变)
3、每次调用select,都需要把fd_set集合从用户态拷贝到内核态,开销较大

IO多路复用——poll

函数原型:
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
typedef struct pollfd {
int fd; // 需要被检测或选择的文件描述符
short events; // 对文件描述符fd上感兴趣的事件
short revents; // 文件描述符fd上当前实际发生的事件
} pollfd_t;
poll的机制与select没有本质差别,监听多个描述符也是进行轮询,根据描述符的状态进行处理,但是poll没有最大文件描述符数量的限制。

IO多路复用——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);
函数说明:
epoll_create 函数创建一个epoll句柄,参数size表明内核要监听的描述符数量。
epoll_ctl 函数注册要监听的事件类型(添加、修改、删除)。
epoll_wait 函数等待事件的就绪,成功时返回就绪的事件数目,调用失败时返回 -1,等待超时返回 0。
优点:
1、没有文件描述符数目限制
2、基于事件驱动,无需轮询文件描述符
3、使用一个文件描述符管理多个描述符,用户空间与内核空间copy较小
两种工作模式:
水平触发(LT):epoll的默认工作模式,当epoll_wait检测到某描述符事件就绪并通知应用程序时,应用程序可以不立即处理该事件;下次调用epoll_wait时,会再次通知此事件;
边缘触发(ET):当epoll_wait检测到某描述符事件就绪并通知应用程序时,应用程序必须立即处理该事件。如果不处理,下次调用epoll_wait时,不会再次通知此事件。
背景:LT和ET原本应该是用于脉冲信号的,Level和Edge指的就是触发点,Level为只要处于水平,那么就一直触发,而Edge则为上升沿和下降沿的时候触发。比如:0->1 就是Edge,1->1 就是Level。
ET模式很大程度上减少了epoll事件的触发次数,因此效率比LT模式下高。

总结

epoll是Linux目前大规模网络并发程序开发的首选模型,在绝大多数情况下性能远超select和poll,但是在并发连接不高的情况下,多线程+阻塞I/O方式可能性能更好。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值