一个理解同步异步阻塞非阻塞非常好的解释

简介: 作者:知乎用户链接:https://www.zhihu.com/question/19732473/answer/51734090来源:知乎著作权归作者所有。
作者:知乎用户
链接:https://www.zhihu.com/question/19732473/answer/51734090
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

以linux下 tcp socket编程为例:

阻塞就是 recv/read的时候 socket接收缓冲区要是有数据就读, 没数据我就一直睡觉赖着不走,直到有数据来了读完我才走。send/write的时候,要是发送缓冲区满了,没有空间继续发送了我也一直睡觉赖着不走,直到发送缓冲区腾出足够的空间让我把数据全部塞到发送缓冲区里我才走。(当然如果你通过setsockopt设置了读写超时,超时时间到了还是会返回-1和EAGAIN,不再睡觉等待)
非阻塞就是recv/read的时候,要是接收缓冲区有数据我就读完,没有数据我直接带着返回的-1和EGAIN走人,绝不睡觉等待耽误时间。write/send的时候, 要是发送缓冲区有足够的空间,就立刻把数据塞到发送缓冲区去,然后走人,如果发送缓存区满了,空间不足,那直接带着返回的-1和EAGAIN走人。

至于IO多路复用,首先要理解的是,操作系统为你提供了一个功能,当你的某个socket接收缓存区有数据可读,或者发送缓冲区有空间可写的时候,它可以给你一个通知。这样当配合非阻塞的socket使用时,只有当系统通知我哪个描述符可读了,我才去执行read操作,可以保证每次read都能读到有效数据而不做纯返回-1和EAGAIN的无用功。写操作类似。操作系统的这个功能通过select/poll/epoll之类的系统调用函数来使用,这些函数都可以同时监视多个描述符的读写就绪状况,这样,多个描述符的I/O操作都能在一个线程内完成,这就叫I/O多路复用,这里的“复用”指的是复用同一个线程。

至于事件驱动,其实是I/O多路复用的一个另外的称呼。

至于异步同步,我们常见的linux下的网络编程模型大部分都是同步io,以读操作为例,本质上都是需要用户调用read/recv去从内核缓冲区把数据读完再处理业务逻辑。异步io则是内核已经把数据读好了,用户直接处理逻辑。异步IO在linux下一般是用aio库。
目录
相关文章
|
1月前
解释一下ConditionVariable的工作原理。
解释一下ConditionVariable的工作原理。
26 6
|
3月前
|
存储 前端开发 JavaScript
【面试题】面试官问:如果有100个请求,你如何使用Promise控制并发?
【面试题】面试官问:如果有100个请求,你如何使用Promise控制并发?
|
28天前
|
JavaScript 前端开发
js开发:请解释同步和异步编程的区别。
同步编程按顺序执行,易理解但可能阻塞程序,适合简单任务;异步编程不阻塞,通过回调、Promise等处理耗时操作,提高效率,适用于并发场景。开发中需根据需求选择合适方式。
11 1
|
3月前
|
Go
Go语言Channel进阶:巧妙运用超时机制
Go语言Channel进阶:巧妙运用超时机制
64 0
|
8月前
|
Java
多线程交替输出A1B2C3D4...你怎么实现?
多线程交替输出A1B2C3D4...你怎么实现?
60 0
对于async和await的使用方式、作用效果不怎么理解 ?没关系,初步看这篇就够了
对于async和await的使用方式、作用效果不怎么理解 ?没关系,初步看这篇就够了
|
10月前
|
Linux
进程间通信——信号原理及详解(附有案例代码)
进程间通信——信号原理及详解(附有案例代码)
|
12月前
|
分布式计算 JavaScript 前端开发
✨从异步讲起,『函数』和『时间』该作何关系?
✨从异步讲起,『函数』和『时间』该作何关系?
|
存储 JavaScript 前端开发
同步异步的原理| 学习笔记
快速学习同步异步的原理。
131 0
同步异步的原理| 学习笔记
|
Java 调度
Java线程同步(含详细解释/代码实例)
Java线程同步(含详细解释/代码实例)
159 0
Java线程同步(含详细解释/代码实例)