IO多路复用

IO多路复用

IO多路复用是一种同步IO模型,实现一个线程可以监视多个文件句柄;一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作;没有文件句柄就绪时会阻塞应用程序,交出cpu。多路是指网络连接,复用指的是同一个线程

• 阻塞IO
• 非阻塞IO
• IO多路复用
• 信号IO
• 异步IO
• select/epoll/poll

作为服务端需要做的事情:(BIO 阻塞IO) 在一个循环中 注意留意马老师的java代码
BIO一个线程对应一个client

网课链接 【https://www.bilibili.com/video/BV1j54y1B7Es?p=2】

• socket = fd5 得到一个文件描述符 在linux中一切皆文件,那么我们怎么能区分出是哪一个文件了?
这个时候就要用到文件描述符
• bind 8090 // socket 绑定一个端口
• listen fd5 //监听状态 等待别人去连接
• accept fd5 = fd6(假设这个就是客户端连进来的文件描述符) //接收看看有没有一个客户端连进来 (会进入一个阻塞状态,有一个客户端连进来才会有一个结果)
• read recvfrom fd6
在这里插入图片描述
以上就是BIO 那么为什么还要接下来发展了? 肯定是资源利用不足,在计算机领域,很多东西都是从资源,也就是性能,和安全的角度考虑
NIO:
BIO的线程比较多,而Java的线程栈只有1M,很快就满了,NIO也就是只需要一个线程来处理所有的client 连接NIO这样性能会提升很多 但是还会有一定的问题,也就是一个线程要轮训所有的client请求看是不是有数据的发送,所以也是很浪费性能 O(n) 次syscall 也是很耗费性能,可能有的client没有数据要传输但是也要被轮循
那么我们是不是可以考虑 有没有更简单的方法 也就是谁有数据就访问谁?
多路复用来了 select epoll poll 但要注意 这些都是返回状态 读写还是要程序自己来
select允许一个线程监控多个文件描述符,而只考虑有需求的client

在这里插入图片描述
但是还是同步!!!
那么这个模型 select 有什么缺点了?
1、每次调用select都要传递所有的文件描述符 会很浪费
2、虽然在外面不会轮询On次了,但是在kernal中还是会轮询N次的,也就是说把外面的压力给内核了,还是
很不好用

那么我们就需要考虑 有没有一个什么样的方法,是不是可以在内核中开辟一段空间来储存文件描述符,而且
对于以前到来的文件描述符就存放在里面,对于新到来的就直接加进来,不用每次都传,同时对于主动遍历,
是不是可以采用一种事件驱动的方式来处理(也就是谁有需求就搞谁),然后在内核中在开辟一个空间来存储
那些已经处理好的结果,程序只需要读取这些数据就可以了?
epoll
在这里插入图片描述
左边的线就是指向内核中的区域,流程就在上面,但是这个时候为什么就节省性能了呢?
epoll 具体过程看图
也就是为什么能解决以上两个问题呢?

主要是因为在内核中有两块特殊的区域,当建立连接,一个区域中就会有很多的fds,不行select epoll不需要把所有的文件描述符都传进来,只需要把新建立的传进来,同时如果有数据需要发送那么只需要把该文件描述符放到右面的区域,那么这个过程是怎么实现的呢?
这就要设计到计组的姿势了。也就是说,当我们的网卡收到来自客户端需要发送的数据的时候,网卡中会有一个缓存,这个时候就会交给DMA,DMA全权掌控数据的传输,当数据传输完成之后,这个时候来一个中断,CPU就会完成数据传送的工作,其他时间CPU就做自己的事情就好了! 这不就是极大程度上解决CPU利用率不高的问题了么!
• nginx redis 用的都是epoll
• redis 轮训 (单线程的日志在逐渐变大)
• nginx 阻塞

在这里插入图片描述
redis 的worker 是单线程,是原子操作,串行化的 使用的是epoll 哪怕我这个时候有十万个线程,但是我使用epoll,只需要告诉我哪个连接有需求就行了 同时redis 对每一个有需要的连接进行的是 读数据,计算,写数据

IO Thread
在这里插入图片描述

redis 为了保证原子化和串行化,因为这样速度比较快,充分发挥性能,开辟了几个线程,因为read/write/compute 都是系统调用,要用到CPU 所以就可以用多线程并发执行,来充分提升系统性能

在这里插入图片描述

零拷贝
在写的时候 使用mmap 相当于一片打通的区域,在写数据的时候,只需要把数据存放在数据空间就行了,以前是需要 用户空间 -> 内核 -> 磁盘 现在使用mmap 可以直接写到磁盘
而零拷贝主要是在读数据的时候, 读数据的时候把数据从磁盘拿出来 放到内核就可以通过socket 直接发出去 不需要到用户空间 这就是零拷贝 那么也就是说 能使用零拷贝的前提就是 数据不需要加工处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值