异步vs非阻塞
2016-05-04 08:16
302 查看
在I/O模型中有两个概念特别容易混淆,就是同步和异步(synchronous vs nonsynchronous),阻塞和非阻塞(blocking vs nonblocking)的区别在什么地方。
同步非阻塞可能吗,异步阻塞有可能吗? 这几个概念在stevens的《UNIX网络编程(卷一)》6.2节写得很清楚,这里写个总结吧。
最流行的I/O模型就是阻塞模型,如果数据没有准备好,那么程序就不会往下运行,一个例子是linux下的系统调用
descriptor没有数据的话,就一直等待用户的输入。
把一个file descriptor设置为非阻塞的意思就是,当数据没有准备好,返回一个错误码。在linux下的一个例子就是在
阻塞和非阻塞比较好理解的,然后我们来看同步和异步。
POSIX这样定义同步和异步:
同步I/O导致请求阻塞,直到I/O操作完成。 异步I/O不导致进程阻塞。
根据同步的定义,我们得知,只要读或写的操作,是在当前线程完成的,在一段时间里只做I/O,其它事情都不能干,那么就是同步I/O。根据异步的定义,如果我们只需要发布一个命令,让小弟(别的线程)去进行读写操作,然后读写完了告诉主线程(通过回调函数),那么就是异步I/O。
NodeJS就是通过小弟线程来实现异步I/O的。其实还有别的方法,比如Linux的AIO,是操作系统层面提供的异步方案,是真正的异步I/O,但它的使用现在非常受限,所以用得不是特别广泛。
简单来说,理解同步异步的关键是谁在进行真正的I/O, 如果是主线程,那么就是同步;如果是小弟线程,小弟线程工作完了报告主线程,那么就是异步。
所以,异步和非阻塞是完全两个概念。但在某些场景下,这两个概念是混用的:当讨论一个API返回速度的时候,异步和非阻塞都是立即返回,在这个上下文中,异步和非阻塞表示的意思相同。
回到我们文章开头的问题:
同步非阻塞可能吗?
当然可能,阻塞和非阻塞I/O都属于同步I/O。
异步阻塞可能吗?
根本就没有这个概念,是我瞎造出来的。不过如果是用I/O线程来实现的“假异步”,线程读数据的依然是阻塞的,这时候勉强可以说是“异步阻塞”。真异步需要操作系统的支持。
这里在顺便说一下,很多人以为epoll就是异步的,这个想法是错的,epoll是同步的,它只是用来告诉你哪个file descriptor可以读写了,至于怎么读怎么写,才是讨论异步或同步I/O的地方。
同步阻塞:read/write,select/poll(有些说法说select是异步阻塞的,但select做的仅仅是告诉你哪些fd准备读写了,然后主线程可以开始读,所以根据定义,它应该还是同步的)。
同步非阻塞:read/write(O_NONBLOCK)
异步非阻塞:Linux上的AIO库
[1] http://www.ibm.com/developerworks/cn/linux/l-async
[2] 《UNIX网络编程》
[3] http://www.cnblogs.com/Jerry-Chou/archive/2012/04/23/2466045.html
原文链接:http://lifeofzjs.com/blog/2014/03/29/sycron-vs-block/
同步非阻塞可能吗,异步阻塞有可能吗? 这几个概念在stevens的《UNIX网络编程(卷一)》6.2节写得很清楚,这里写个总结吧。
阻塞I/O
最流行的I/O模型就是阻塞模型,如果数据没有准备好,那么程序就不会往下运行,一个例子是linux下的系统调用read和
write,如果调用了read,但是file
descriptor没有数据的话,就一直等待用户的输入。
非阻塞I/O
把一个file descriptor设置为非阻塞的意思就是,当数据没有准备好,返回一个错误码。在linux下的一个例子就是在read之前,调用
fcntl将
O_NONBLOCK作为参数,将fd设为非阻塞的。如果read返回错误码,那么就接着read,如此反复,这种方法叫轮询,浪费cpu时间。
阻塞和非阻塞比较好理解的,然后我们来看同步和异步。
同步/异步IO
POSIX这样定义同步和异步:同步I/O导致请求阻塞,直到I/O操作完成。 异步I/O不导致进程阻塞。
根据同步的定义,我们得知,只要读或写的操作,是在当前线程完成的,在一段时间里只做I/O,其它事情都不能干,那么就是同步I/O。根据异步的定义,如果我们只需要发布一个命令,让小弟(别的线程)去进行读写操作,然后读写完了告诉主线程(通过回调函数),那么就是异步I/O。
NodeJS就是通过小弟线程来实现异步I/O的。其实还有别的方法,比如Linux的AIO,是操作系统层面提供的异步方案,是真正的异步I/O,但它的使用现在非常受限,所以用得不是特别广泛。
简单来说,理解同步异步的关键是谁在进行真正的I/O, 如果是主线程,那么就是同步;如果是小弟线程,小弟线程工作完了报告主线程,那么就是异步。
所以,异步和非阻塞是完全两个概念。但在某些场景下,这两个概念是混用的:当讨论一个API返回速度的时候,异步和非阻塞都是立即返回,在这个上下文中,异步和非阻塞表示的意思相同。
回到我们文章开头的问题:
同步非阻塞可能吗?
当然可能,阻塞和非阻塞I/O都属于同步I/O。
异步阻塞可能吗?
根本就没有这个概念,是我瞎造出来的。不过如果是用I/O线程来实现的“假异步”,线程读数据的依然是阻塞的,这时候勉强可以说是“异步阻塞”。真异步需要操作系统的支持。
这里在顺便说一下,很多人以为epoll就是异步的,这个想法是错的,epoll是同步的,它只是用来告诉你哪个file descriptor可以读写了,至于怎么读怎么写,才是讨论异步或同步I/O的地方。
一些例子
同步阻塞:read/write,select/poll(有些说法说select是异步阻塞的,但select做的仅仅是告诉你哪些fd准备读写了,然后主线程可以开始读,所以根据定义,它应该还是同步的)。同步非阻塞:read/write(O_NONBLOCK)
异步非阻塞:Linux上的AIO库
References
[1] http://www.ibm.com/developerworks/cn/linux/l-async[2] 《UNIX网络编程》
[3] http://www.cnblogs.com/Jerry-Chou/archive/2012/04/23/2466045.html
原文链接:http://lifeofzjs.com/blog/2014/03/29/sycron-vs-block/
相关文章推荐
- DB2 数据库之数据打平函数
- Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)
- Java代码中单例模式总结
- mysql 登录、退出
- Spark笔记一之启动、简单RDD、提交、测试
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- MVC5+EF6 入门完整教程12--灵活控制Action权限
- Unity3D入门(rolling ball)——学习笔记
- jQuery的ajax使用场景讨论(c#)
- tda2822功放
- ASP.NET 状态管理(视图状态 ViewState)
- 打电话、发短信、web以及发邮件
- 数据研发工程师实习面试问题记录一
- js笔记01
- 八皇后问题
- linux core文件
- Linux script and scriptreplay(三)
- (404) 未找到 获取StatusCode状态码
- 【BZOJ1854】【codevs3358】游戏,二分图最大匹配
- MAC,IP,路由传输封装过程