BIO NIO SELECT EPOLL

BIO

BIO即为阻塞IO调用,想要read一个文件或者write一个文件,都是通过文件描述符即FD去关联。

现在有一个线程想要读取FD8,当FD8没有数据返回时,这个线程就阻塞着,没有数据就等,有数据就返回。

一个线程对应一个连接也就是管理一个FD,当现有线程阻塞时。想要读取新的文件只能通过开辟新的线线程,这就是BIO时期

NIO

NIO非阻塞同步io,由于线程数量是有限的。

NIO时期,线程不会阻塞,一个线程可以通过轮询的方式去查询,获取哪个fd有数据返回。

系统分为用户空间和内核空间,轮询发生在用户空间,线程虽然不会阻塞,但是一次查询就是一次系统调用,当线程需要轮询的fd数量变多,带来的成本问题随之变高。

NIO的问题在于,线程并不知道哪个FD有数据了,只能拿着一个一个去问,那么能不能变成有数据的主动通知,答案是可以的,这就引入了SELECT

SELCET

假如现在有1000个fd,线程统一把这些fd传给select,由内核监控哪些有数据返回,然后线程再拿着准备好的fd再来调用,避免了用户空间发生的轮询带来的成本,但是随之产生的问题是fd相关数据来回在用户空间和系统空间拷贝。

EPOLL

为了解决SELECT带来的问题,引入EPOLL,即在用户空间和系统空间开辟出一个共享空间,

epoll是一个整体,包含epoll_create 、epoll_ctl、epoll_wait三个系统调用。

共享空间,进程把fd存放红黑树,内核通过红黑树拿fd去查哪个io数据到达,把到达的放到链表里。然后进程从链表取对应的fd。

大致过程如下:

1.进程先调用epoll的create,创建一个epoll文件描述符;

epoll通过mmap开辟一块共享空间,增删改由内核完成,查询则内核和用户进程都可以

这块共享空间中有一个红黑树和一个链表

2.进程调用epoll的ctl add/delete sfd,把新来的链接放入红黑树中,

2.1进程调用wait(),等待事件(事件驱动)

3.当红黑树中的fd有数据到了,就把它放入一个链表中并维护该数据可写还是可读,wait返回;

4.上层用户空间(通过epoll)从链表中取出fd,然后调用read/write读写数据.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值