阻塞IO和非阻塞IO的区别

定义

阻塞是进程的一种状态,表示等待某个事件发生(如读写操作需要等待数据),进程阻塞就表示暂停执行了,和挂起类似。

  • 阻塞IO:称阻塞的文件描述符为阻塞IO
  • 非阻塞IO:称非阻塞的文件描述符为非阻塞IO

see: Linux高性能服务器编程 游双 P126

区别

阻塞IO

针对阻塞IO的系统调用(如read, write)可能因为无法完成而被系统挂起,直到等待的事件发生为止。举例:read和write,通常IO操作都是阻塞I/O的,也就是说当你调用read时,如果没有数据收到,那么线程或者进程就会被挂起,直到收到数据。
坏处:see: I/O多路复用技术(multiplexing)是什么? - 用心阁的回答 - 知乎
https://www.zhihu.com/question/28594409/answer/74003996

由于服务器可能要处理很多的连接,对于大部分的连接来说都是阻塞的,采用阻塞IO的模式可能会导致线程或者进程之间频繁切换,造成很大的系统开销。举个例子:当服务器需要处理1000个连接的的时候,而且只有很少连接忙碌的,那么会需要1000个线程或进程来处理1000个连接,而1000个线程大部分是被阻塞起来的。由于CPU的核数或超线程数一般都不大,比如4,8,16,32,64,128,比如4个核要跑1000个线程,那么每个线程的时间槽非常短,而线程切换非常频繁。这样是有问题的:

  • 线程是有内存开销的,1个线程可能需要512K(或2M)存放栈,那么1000个线程就要512M(或2G)内存。
  • 线程的切换,或者说上下文切换是有CPU开销的,当大量时间花在上下文切换的时候,分配给真正的操作的CPU就要少很多。

PS :实际上可能不需要这么多的线程,可以采用线程池的模式。
在这里插入图片描述
如上图所示,read直到数据复制到应用进程的缓冲区或者发生错误才会返回,这就是阻塞的定义:等待某个事件。

非阻塞IO

针对非阻塞IO的系统调用总是立刻返回,不管事件是否发生,如果事件没有立刻发生就返回-1,并且设置errno,就类似于出错了。对于accept,recv 和 send,事件未发生时,errno 通常被设置成 EAGAIN。
在这里插入图片描述

好处:如果等待的事件没有发生,如上图中所示的read数据未准备好,系统调用会立即返回而不是导致调用进程被挂起。
坏处:用户进程需要采用轮询的方式(逐个查找)查看事件状态,这往往耗费大量的CPU资源。

参考资料

Linux高性能服务器编程 游双
I/O多路复用技术(multiplexing)是什么? - 用心阁的回答 - 知乎
https://www.zhihu.com/question/28594409/answer/74003996

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值