BIO NIO select epoll并图解举例

Posted 一口Linux

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BIO NIO select epoll并图解举例相关的知识,希望对你有一定的参考价值。

BIO

操作系统内核提供 read(系统调用),读文件描述符;一个client连接就是一个文件描述符fd ;socket为阻塞的,socket产生的文件描述符,如左边的fd8,当数据包没到的时候,上面左边read不能返回,阻塞着。

即有一个client连接,就需要开一个进程(或者线程),读这个连接,有数据就处理,没数据就阻塞着。

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

BIO NIO select epoll并图解举例(转载)

 

NIO

linux内核提供的socket可以是非阻塞的。通过man 2 socket。查看帮助文档。int socket(int domain, int type, int protocol)。在type的参数中设置SOCK_NONBLOCK标志,代表非阻塞。

BIO NIO select epoll并图解举例(转载)

 

既然socket不阻塞了,那么一个进程(线程)就够了。在进程里面写循环,即一个个问fd有没数据,即轮询,发生在用户空间。

遍历,取出来自己处理,这为同步非阻塞。

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

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

AIO

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

select epoll

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

以上是关于BIO NIO select epoll并图解举例的主要内容,如果未能解决你的问题,请参考以下文章

NIO多路复用底层原理(SelectPollEPoll)

[Linux网络编程]多路IO复用Epoll Select问题补充

从底层入手,图解 Java NIO BIO MIO AIO 四大IO模型与原理

Netty_02_高性能的NIO框架

Netty_02_高性能的NIO框架

nio select poll epoll