IO模型
2022-06-27 19:12:26 0 举报
BIO,NIO,EPOLL
作者其他创作
大纲/内容
fd 9
fd 8
clone threadread fd 8
Kernel
clone threadread fd 9
用户态
Non Blocking IO多路复用NIO(JVM调用的)1. 用户程序调用内核select,传入1000fds2. 内核主动遍历1000次,返回这1000fds状态3. 用户程序轮询查看fds状态,成功的再去调用内核read/write
SystemCall(系统调用)
双向链表
Client
内核态
用户空间程序轮询读取文件描述符,并处理read fd 8 read fd 9
User Program
3. read / write
NIO
轮询
2 . 返回状态
fd(file discriptor):文件描述符,代表有执行IO操作的系统调用。(Linux系统一切皆文件)
ThreadA
红黑树
BIO
select(fds)
2. 事件驱动
Non Blocking IOSocket是Non Blocking,是非阻塞的系统内核支持Non Blocking IO,这个时候用户空间只需要一个线程轮询处理系统调用,read / write即可。例如:此时有两个客户端连接进来,主线程去做系统调用后,接着read fd 8 ,计算,write fd 8,然后read fd 9,计算,write fd 9,此时是同步非阻塞。
Blocking IOSocket是Blocking,是阻塞的服务端启动后主线程会循环等待客户端来连接,呈阻塞状态(accept是阻塞方法),此时,当有两个客户端连接进来时(fd8,fd9各表示1个Socket连接),用户空间程序会相应的clone两个线程去处理请求,每个线程对应处理一个Client请求。且这两个请求的输入或输出也是阻塞的。(read/write是阻塞方法)
内核程序select
遍历
用户程序accept
问题:1. 成本问题:有1000fd,就要系统调用1000次,成本很大
内核程序accept
1. select(fds)
accept
read/write都是阻塞的
用户程序传fds
问题:1. 核心问题:阻塞2. 线程多,消耗资源,同时系统调用也多,线程之间的切换慢
1. epoll_create
fd 5 = socket (blocking) bind 8090listen fd 5fd 8 = accept fd 5recvfrom fd 8accept是阻塞的,等待客户端请求
fd 5 = socket (non blocking) bind 8090listen fd 5fd 8 = accept fd 5recvfrom fd8同步非阻塞,来一个连一个,处理一个
mmap
问题:1. 读和写需要把fd相关数据来回拷贝,传递数据成本比较高2. 最大读数也有上限(默认1024)
ThreadB
epoll
Non Blocking IOepoll(JVM调用的)1. 用户程序调用内核epoll_create创建一个eventpoll对象,再通过epoll_ctl将需要监听的socket放入到eventpoll对象的rbr(红黑树)中,同时,会给内核中断处理程序注册一个回调函数,告诉内核,如果这个句柄的中断到了,就把它放到rdlist(就绪链表)里2. 网卡接收到数据,会对CPU发起硬中断,内核执行回调函数,把网卡上的数据写入rdlist(就绪链表)里,当执行epoll_wait时立刻返回准备就绪链表里的数据3. 用户程序取链表中fd做实际的read/write操作
共享空间
0 条评论
下一页