node.js 的异步模型

node.js 的异步模型

一、基本概念
阻塞式IO:cpu一直等到数据准备好了之后才会工作,即从函数调用开始,一直到数据准备好这段时间cpu是干等着的
非阻塞式的IO:数据准备好了之后发一个信号,此后cpu才会处理,即cpu不会干等着

阻塞式:相当于是轮训、非阻塞式相当于是中断

同步执行:语句的先后顺序就是cpu执行指令的顺序
异步执行:写在前面的语句不一定先执行,具体执行的时间不确定(一般是事件触发的)

可以看出,非阻塞io肯定要与异步执行结合才能保证程序逻辑的正确性,node.js中使用的是非阻塞的io

二、初衷
node.js的初衷是解决IO密集型的应用(与此相对的是cpu密集型)。在实际应用中,为了实现应用层的并发性,大多数程序都会使用多线程或者是多进程(尤其是server这种需要同时并发对外提供服务的程序)。程序逻辑一般都会处理数据,当出现数据冲突时多线程必须串行执行(即加锁),这样的话多开的线程实际上是没有达到并发的效果的,同时因为多线程时CPU要频繁的调度,反而会增加系统负担(对于实时性的server 如网游服务器,IM服务器等一般都不会开很多的线程,这些server最大的瓶颈都是网络或数据库等IO操作)。经过分析可知,系统的瓶颈主要是在IO上,即cpu执行的快没有用,整个程序的性能是综合的结果,从吞吐率上来说,多线程并没有比单线程快多少。

三、node.js的哲学
既然瓶颈是在IO,那我就对付这个IO。所以node.js采用单线程执行模型:所有需要cpu等待的东西,全部移出执行队列,等到IO执行好了之后,再放入一个回调进来。这样做的话,cpu就会一直做‘有意义’的事情。
这样做的好处:1、不用多线程,所以不用加锁、不用调度, cpu的吞吐率高很多。2、不用处理线程同步带来的n多的诡异问题。
坏处:要求程序员要有异步的思维模式,即下一行代码不一定是在什么时候执行。如果逻辑间有前后依赖关系,一定要将后面的逻辑放入回调中。

三、单线程模型下如何实现用户级的并发 -----------基于事件的timer
执行模型是单线程的,但是应用的逻辑可能要求是并发的,那么该如果实现用户级的并发呢?如果用c语言来实现,一般采用 经典的消息队列+ worker thread + 回调函数,
在node.js中,一般是使用timer,如果是无限循环的逻辑 一般包装一个scheduler就OK了。

四、node.js实现的异步事件的相关源代码(c实现)
node.js利用uvlib来实现跨平台,windows下事件循环的实现 在uvlib的 src/win/core.c --------UV_LOOP_ONCE

此宏的主要代码如下:
uv_update_time((loop)); \
uv_process_timers((loop)); \
\
/* Call idle callbacks if nothing to do. */ \
if ((loop)->pending_reqs_tail == NULL && \
(loop)->endgame_handles == NULL) { \
uv_idle_invoke((loop)); \
} \
\
uv_process_reqs((loop)); \ 先处理
uv_process_endgames((loop)); \
\
if ((loop)->refs <= 0) { \
break; \
} \
\
uv_prepare_invoke((loop)); \
\
poll((loop), (loop)->idle_handles == NULL && \ 后收集事件
(loop)->pending_reqs_tail == NULL && \
(loop)->endgame_handles == NULL && \
(loop)->refs > 0); \
\
uv_check_invoke((loop));

概括一下:执行引擎是一个无限循环的过程,每一次的循环都可以看做一个tick()。 一个tick内基本逻辑是
1、更新全局定时器,
2、检查timer是否到期(到的话就放入执行队列,在下一个tick中来执行),
3、执行此tick内的所有回调 -------schedule的过程
4、检查是否要退出
5、从OS处取出网络socket,文件操作等IO完成事件,

PS:因为每个tick要处理的事件数量是随机的,所以2个tick间的deltaTime不是固定不变的,所以node.js不保证帧率而是保证吞吐率,所以每一次tick的顺序是schedule(), poll()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值