通俗理解BIO NIO select epoll并图解举例

BIO

在这里插入图片描述
操作系统内核提供 read(系统调用),读文件描述符
一个client连接就是一个文件描述符fd
socket为阻塞的,socket产生的文件描述符,如左边的fd8,当数据包没到的时候,上面左边read不能返回,阻塞着。
即有一个client连接,就需要开一个进程(或者线程),读这个连接,有数据就处理,没数据就阻塞着。

问题:几个连接几个进程(线程),一个cpu在某一时间片上,只能一个进程(线程)处理,如果自己的数据还没到,就算另外一个数据到了,也没办法处理。造成cpu资源浪费,没办法时刻处理到达的数据。而且开这么多进程(线程)是有成本的。

NIO

linux内核提供的socket可以是非阻塞的。通过man 2 socket。查看帮助文档。int socket(int domain, int type, int protocol)。在type的参数中设置SOCK_NONBLOCK标志,代表非阻塞。
在这里插入图片描述
既然socket不阻塞了,那么一个进程(线程)就够了。在进程里面写循环,即一个个问fd有没数据,即轮询,发生在用户空间。
遍历,取出来自己处理,这为同步非阻塞。

问题:如果有很多fd(假设1000个),代表用户进程需要轮询调用1000次内核(查一次文件描述符就需要一次系统调用)。这带来成本问题,因为用户态与内核态反复切换(cpu保护现场恢复现场)。当然了,如果连接数少的情况,这个开销就不大。

解决:引入后面select poll epoll。减少系统调用,这在用户空间实现是实现不了的,所以解决方式是在内核解决。

AIO

Linux 上目前没有像 IOCP(windows) 这样的成熟异步 IO 实现。目前来看,windows才有真正AIO。

select epoll

在这里插入图片描述

select

假设1000个fd,进程统一把1000个fd传select,内核监控这些,发现哪些fd准备好,则返回fd。然后进程拿准备好的fd再调用read。即多路复用,选择谁数据有了,直接执行。减少用户态和内核态切换。

问题: 每次需要把1000个fd传,再返回。用户态和内核需要拷来拷去fd。可优化!
解决:引入 epoll
延伸–> mmap
共享空间,内核<–>用户,即把1000个fd写入共享空间

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读写数据.

mmap和零拷贝

零拷贝senfile:
比如读文件然后通过网卡把数据传出去
网卡到内核 socket io,file到内核 文件io,2个io,2个fd。那么需要先read 文件的fd,然后再write 把文件写出去,2个系统调用,发生在内核态。即文件数据先要到内核buffer缓冲区,然后read系统调用拷贝到用户空间,然后再系统调用把内容拷到内核空间。有了senfile后,就不用多了拷贝,即直接内核读缓冲区数据直接通过网卡写出去。

mmap:
用户空间和内核空间是相互独立的,mmap用于把文件映射到内存空间中,简单说mmap就是把一个文件的内容在内存里面做一个映射。映射成功后,用户对这段内存区域的修改可以直接反映到内核空间,同样,内核空间对这段区域的修改也直接反映用户空间。

  • 37
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 30
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lovelife110

你的鼓励是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值