IO多路复用
- 1. 什么是IO?
- 2. 什么是IO多路复用?
- 3. 为什么有IO多路复用机制?
- 同步阻塞(BIO)
- 同步非阻塞(NIO)
- IO多路复用
- 4. IO多路复用的三种实现方式?
- select
- poll
- epoll
1. 什么是IO?
IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。
由于CPU和内存的速度远远高于外设的速度,所以,在IO编程中,就存在速度严重不匹配的问题。因此,存在两种方法:
第一种是CPU等着,也就是程序暂停执行后续代码,等数据写入磁盘后,再接着往下执行,这种模式称为同步IO;
另一种方法是CPU不等待,只是告诉磁盘,“您老慢慢写,不着急,我接着干别的事去了”,于是,后续代码可以立刻接着执行,这种模式称为异步IO。
2. 什么是IO多路复用?
IO多路复用是一种同步IO模型,实现一个线程可以监视多个文件句柄;一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作;没有文件句柄就绪时会阻塞应用程序,交出cpu。多路是指网络连接,复用指的是同一个线程
3. 为什么有IO多路复用机制?
如果不使用IO多路复用,可以用阻塞IO(BIO)和非阻塞IO,但是会有一些问题
同步&异步
同步和异步关注的是消息通信机制 (synchronous communication/asynchronous communication)
同步请求,A调用B,B的处理是同步的,在处理完之前他不会通知A,只有处理完之后才会明确的通知A。
异步请求,A调用B,B的处理是异步的,B在接到请求后先告诉A我已经接到请求了,然后异步去处理,处理完之后通过回调等方式再通知A。
同步和异步最大的区别就是被调用方的执行方式和返回时机。
同步指的是被调用方做完事情之后再返回,异步指的是被调用方先返回,然后再做事情,做完之后再想办法通知调用方。
阻塞&非阻塞
阻塞请求,A调用B,A一直等着B的返回,别的事情什么也不干。
非阻塞请求,A调用B,A不用一直等着B的返回,先去忙别的事情了。
阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回。
非阻塞:不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.
同步、异步说的是被调用者会不会通知,阻塞、非阻塞说的是调用者会不会卡住不动。
同步是个过程,阻塞是线程的一种状态。
也就是说 同步或者异步只是会不会通知而已,不管你阻不阻塞(同步阻塞和同步费非阻塞)
阻塞 表示线程停止了
同步阻塞(BIO)
- 服务端采用单线程,当accept一个请求后,在recv或send调用阻塞时,将无法accept其他请求(必须等上一个请求处recv或send完),无法处理并发
- 服务器端采用多线程,当accept一个请求后,开启线程进行recv,可以完成并发处理,但随着请求数增加需要增加系统线程,大量的线程占用很大的内存空间,并且线程切换会带来很大的开销,10000个线程真正发生读写事件的线程数不会超过20%,每次accept都开一个线程也是一种资源浪费
同步非阻塞(NIO)
- 服务器端当accept一个请求后,加入fds集合,每次轮询一遍fds集合recv(非阻塞)数据,没有数据则立即返回错误,每次轮询所有fd(包括没有发生读写事件的fd)会很浪费cpu
IO多路复用
- 服务器端采用单线程通过select/epoll等系统调用获取fd列表,遍历有事件的fd进行accept/recv/send,使其能支持更多的并发连接请求
4. IO多路复用的三种实现方式?
select、poll、epoll
select
poll
epoll