(BAT必会知识)Linux网络编程中五种IO模型讲解

370 阅读5分钟

什么是阻塞非阻塞?什么是同步异步?

🌰 洗衣机洗衣服的例子

无论是阻塞式IO 还是非阻塞式IO,本质上都是同步IO模型!

  • 同步阻塞:你将衣服放到洗衣机洗,然后看着洗衣机洗完,洗好后再去晾衣服(你就干等,什么都不做,堵塞在那) 但你要的结果只是晾衣服,你等待的这个过程就是阻塞
  • 同步非阻塞:你将衣服放到洗衣机洗,然后可以去做其他事,比如玩游戏或看电视之类的,但你要定时去看看洗衣机有没有洗完,洗完后再去晾衣服
  • 异步阻塞:你将衣服放到洗衣机洗,然后看着洗衣机洗完,洗完后洗衣机发出提示音告诉你洗完了,再去晾(先说一下,生活中你会这样么?所以说几乎没有这个情况,没这个说法,可以忽略)用异步就不会出现阻塞这种情况!
  • 异步非阻塞:你将衣服放到洗衣机洗,去做其他事,洗衣机洗好后自动晾衣服,晾好后放个音乐提示你衣服晾好了

因为有了IO操作才会有阻塞,才会出现同步和异步。!

因为有大量的IO操作,才会有高并发设计,如果只是纯CPU计算,不涉及到CPU对外围IO设备的读写,那么就不存在高并发设计!

对于CPU而言,开一个线程计算和开100线程计算,只会徒增CPU切换时间,当然这种情况下也存在所谓的阻塞、非阻塞、同步和异步。所谓的高性能就是如何在处理大量IO的情况下,让CPU干更多的事

详解五种IO模型

IO的操作分为两步:发起IO请求等待数据准备,实际IO操作(洗衣服,晾衣服)

同步需要主动读写数据,在读写数据的过程中还是会堵塞(好比晾衣服堵塞了你)

异步仅仅需要IO操作完毕的通知。并不主动读写数据,有操作系统内核完毕数据的读写(机器人帮你晾衣服)

五种IO模型:阻塞IO、非阻塞IO、多路复用IO、信号驱动IO、异步IO

前四种都是同步IO,因为在内核数据copy到用户空间时都是阻塞的

推荐书籍:RFC标准或数据《UNIX Network Programming》中文《UNIX网络编程-卷-》第六章

Type2:阻塞IO

等待数据准备到复制数据 整体都是阻塞的,什么都干不了就干等着

WechatIMG246.png

Type2:非阻塞IO

取数据过程中,内核告诉你没准好,过一会你又过来看,内核告诉你还没准备好,但这个过程你可以去看别的,玩玩游戏看电视什么的,但需要时不时的去检查,当内核准备好数据拷贝后返回,但实际拷贝数据这个过程也是阻塞的

WechatIMG247.png

Type3:IO多路复用

一个线程处理多个连接

线程会监听多个请求,会轮询,哪个好了就操作哪个,但在拷贝数据时也是阻塞的,属于同步IO

比上面好的优点是:更多线程可以处理更多连接

I/O多路复用是阻塞在select,epoll这样的系统调用,没有阻塞在真正的I/O系统调用如recvfrom
进程受阻于select,等待可能多个套接口中的任一个变为可读
    
IO多路复用使用两个系统调用(select和recvfrom)
blocking IO只调用了一个系统调用(recvfrom)
select/epoll 核心是可以同时处理多个connection,而不是更快,所以连接数不高的话,性能不一定比多线程+阻塞IO好
多路复用模型中,每一个socket,设置为non-blocking,
阻塞是被select

WechatIMG249.png

Type4:信号驱动IO

很少很少用到!

WechatIMG250.png

Type5:异步IO(POSIX的aio_系列函数)

Future-Listener机制

你是一个进程或线程 由其他模块帮你去完成 你不能卡主

好比你是个大哥 你有点事告诉小弟去办 这个期间你去忙别的 小弟完成后告诉你完成了

1.进程调用直接返回 主进程去干其他事情

2.内核主动去复制用户空间 指定信号

WechatIMG251.png

总结

1.IO操作分为两步 第一步发起IO请求,等待数据准备 这里是阻塞IO和非阻塞IO的区别 第二步实际的IO操作,将数据从内核拷贝到进程中,这里是同步IO和异步IO的区别

2.前四种IO模型都是同步IO,区别在于第一阶段,而他们的第二阶段都是相同的,数据从内核copy到应用缓冲区期间都是阻塞的,进程阻塞于recvfrom调用或者select()函数,相反,异步I/O模型在这两个阶段都要处理

3.阻塞IO和非阻塞IO的区别在于第一步,发起IO请求是否会被阻塞,如果阻塞知道完成那么就是传统的阻塞IO,如果不阻塞。那么就是非阻塞IO

4.同步IO和异步IO的区别在于第二步是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO,因此阻塞IO、非阻塞IO、多路复用IO、信号驱动IO都是同步IO,如果不阻塞,而是操作系统帮你完成IO操作再将结果返回给你,那么就是异步IO

重点

几个核心点:
   阻塞非阻塞说的是线程的状态(重要)
   同步和异步说的是消息的通知机制(重要)
   
   同步需要主动读写数据,异步是不需要主动读写数据
   同步IO和异步IO是针对用户应用程序和内核的交互

WechatIMG244.jpeg

感觉不错的大佬点个赞呗~ 手敲截图演示不易