您的位置:首页 > Web前端 > Node.js

nodejs学习日志4--异步IO

2013-12-23 10:36 260 查看
初识异步是在ajax的请求中,node是首个将异步作为主要编程方式和设计理念的。

B/S模型中,前端通过异步请求资源可以消除UI阻塞的现象,但是前端获取资源的速度也取决于后端的响应速度。例如请求两个资源A和B,A需x,B需y,同步的情况下需要时间是x+y,异步的情况下就是max(x,y),取决于时间长的请求,A不阻塞B,B不依赖A的结束。在分布式情况下同步和异步的差异会更大,且不说CPU的各级缓存和内存的I/O,网络I/O和磁盘I/O都是非常耗时的操作,所以异步I/O就显得非常重要。后端的资源响应速度的快慢直接影响到前端的用户体验。

在计算机资源中,通常I/O与CPU计算之间是可以并行进行的,单线程同步编程模型会因阻塞I/O导致硬件资源得不到更优利用,多线程又面临死锁,状态同步等问题,而node正是利用单线程和异步I/O,但是单线程无法利用多核CPU(?),另外阻塞I/O造成CPU等待浪费,非阻塞需要轮询去确认数据是否完全 获取,它会让CPU处理状态判断,对CPU也是浪费,轮询技术的演进:

read

select

poll

epoll

kqueue(freebsd系统下)

select和epoll比较形象的对比可以参考
http://weibo.com/1711278761/zpzMyhndl

轮询技术满足了非阻塞I/O确保数据的完整的需要,但应用程序依然需要花费时间等待完全数据的返回,等待期间CPU也得不到充分利用。

node的异步I/O:事件循环,观察者,请求对象,I/O线程池这四者共同构成了node异步I/O模型的基本要素,window下通过IOCP来向系统内核发送I/O调用和从内核获取已完成的I/O操作,配以事件循环完成异步I/O过程。在Linux下通过epoll实现这个过程,FreeBsd下通过kqueue实现,不同的是线程池在Windows下由内核(IOCP)直接提供,×nix系列下有libuv自行实现。


node是单线程的,这里的单线程仅仅是JavaScript执行在单线程中,内部完成I/O任务另有线程池,node自身其实是多线程的,只是I/O线程使用的CPU较少。除了用户代码无法并行执行,所有的I/O是可以并行起来的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: