博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个理解同步异步阻塞非阻塞非常好的解释
阅读量:6578 次
发布时间:2019-06-24

本文共 927 字,大约阅读时间需要 3 分钟。

作者:知乎用户
链接: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库。
你可能感兴趣的文章
PHP多进程编程(2):管道通信
查看>>
【HTML5】Canvas和SVG的区别
查看>>
李洪强经典面试题8
查看>>
wireshark怎么抓包、wireshark抓包详细图文教程
查看>>
mysql 源码调试方法
查看>>
Asp.Net微信登录-手机网站APP应用
查看>>
用git管理自己读的书
查看>>
JS 数字转换为大写金额
查看>>
EASYUI 表单(FORM)用法
查看>>
[唐诗]187春思-李白
查看>>
SQL语言 之 事务控制
查看>>
详解C中的volatile关键字【转】
查看>>
tableviewCell的xib中collectionView签协议
查看>>
java基础之导出(Excel)
查看>>
JavaScript之面向对象学习三原型语法升级
查看>>
最新AndroidSDK安装教程
查看>>
【USACO 1.4】Arithmetic Progressions
查看>>
Eclipse linux tools 插件
查看>>
可重入锁 & 自旋锁 & Java里的AtomicReference和CAS操作 & Linux mutex不可重入
查看>>
使用Redis来实现LBS的应用
查看>>