linux select 消息队列,linux IO模型 (IO多路复用的三种机制Select,Poll,Epoll)

BIO -> 普通NIO -> select NIO -> epoll 同步非阻塞多路复用

linux内核优化的结果

linux内核没有实现异步IO

同步:轮询socket和读取数据的线程都是用户线程

非阻塞:线程轮询socket 没有数据的时候不会阻塞

BIO

8c32a88b248a

每一个socket都需要一个线程去阻塞读取

recvfrom系统调用一直是阻塞的 一个线程处理一个socket

问题:多个线程、线程切换

普通NIO

8c32a88b248a

一个线程一次次的发起对socket的轮训,recvfrom调用没数据就返回,有数据就同步处理

yum install man man-pages

man 2 read 系统调用文档

linux 面向文件描述符 cd /proc/pid/fd

问题:连接多的时候,需要一次次系统调用

select NIO

8c32a88b248a

多路复用:一个线程管理多个socket 适合连接数比较多的情况

selectort.select() 内核中的系统调用,查询每个socket是否有数据事件到达,如果没有会一直阻塞,导致用户线程的阻塞

select 轮询每个socket的状态是在内核空间进行的,效率高,之前在用户空间发起

返回给用户空间的是所有的socket还是有数据的socket ??

问题:1 需要遍历文件描述符 2 需要在用户空间和内核空间传递文件描述符

poll相对于select来讲,没有了最大连接数的限制

epoll

8c32a88b248a

信号驱动IO?

就绪列表 / mmap

epoll 数据结构: 双向链表 / 红黑树

系统调用:epoll_create epoll_ctl epoll_wait

异步IO

linux内核没有实现 windows内核实现了

异步IO模型才是最理想的IO模型,在异步IO模型中,当用户线程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从内核的角度,当它受到一个asynchronous+read之后,它会立刻返回,说明read请求已经成功发起了,因此不会对用户线程产生任何block。然后,内核会等待数据准备完成,然后将数据拷贝到用户线程,当这一切都完成之后,内核会给用户线程发送一个信号,告诉它read操作完成了。也就说用户线程完全不需要关心实际的整个IO操作是如何进行的,只需要先发起一个请求,当接收内核返回的成功信号时表示IO操作已经完成,可以直接去使用数据了。

也就说在异步IO模型中,IO操作的两个阶段都不会阻塞用户线程,这两个阶段都是由内核自动完成,然后发送一个信号告知用户线程操作已完成。用户线程中不需要再次调用IO函数进行具体的读写。这点是和信号驱动模型有所不同的,在信号驱动模型中,当用户线程接收到信号表示数据已经就绪,然后需要用户线程调用IO函数进行实际的读写操作;而在异步IO模型中,收到信号表示IO操作已经完成,不需要再在用户线程中调用iO函数进行实际的读写操作。

mmap系统调用

零拷贝

sendfile系统调用 / 消息队列kafka MQ接收网络存储的消息并保存也是零拷贝(网络 -> mmap内存映射 -> 磁盘)

8c32a88b248a

零拷贝.png

处理IO -> 处理文件描述符

socket 文件描述符file 关系?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值