前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >通俗理解BIO NIO select epoll并图解举例

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

作者头像
lovelife110
发布2021-01-14 16:23:36
1.2K0
发布2021-01-14 16:23:36
举报
文章被收录于专栏:爱生活爱编程爱生活爱编程

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就是把一个文件的内容在内存里面做一个映射。映射成功后,用户对这段内存区域的修改可以直接反映到内核空间,同样,内核空间对这段区域的修改也直接反映用户空间。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • BIO
  • NIO
  • AIO
  • select epoll
    • select
      • epoll
        • mmap和零拷贝
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档