`
eric_weitm
  • 浏览: 235363 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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()
分享到:
评论

相关推荐

    Node.js 开发指南.pdf

    第1章 Node.js简介 1 1.1 Node.js是什么 2 1.2 Node.js能做什么 3 1.3 异步式I/O与事件驱动 4 1.4 Node.js的性能 5 1.4.1 Node.js架构简介 5 1.4.2 Node.js与PHP+Nginx 6 1.5 JavaScript简史 6 ...

    Node.js(node-v21.6.0.tar.xz)

    Node.js提供了一个非阻塞I/O模型,使其轻量且高效,特别适合于实时、高并发的网络应用,如聊天室、实时通信应用等。 Node.js的应用场景主要包括以下几个方面: 实时Web应用:由于Node.js的异步和事件驱动的特性,...

    Node.js+开发指南

    第1章 Node.js简介 1 1.1 Node.js是什么 2 1.2 Node.js能做什么 3 1.3 异步式I/O与事件驱动 4 1.4 Node.js的性能 5 1.4.1 Node.js架构简介 5 1.4.2 Node.js与PHP+Nginx 6 1.5 JavaScript简史...

    Node.js MongoDB AngularJSWeb开发中文版.part1

    4.1 了解Node.js事件模型 51 4.1.1 比较事件回调和线程模型 51 4.1.2 在Node.js中阻塞I/O 52 4.1.3 会话示例 54 4.2 将工作添加到事件队列 54 4.2.1 实现定时器 55 4.2.2 使用nextTick来调度工作 58 4.2.3 实现事件...

    Node.js-14-Cookbook:Node Cookbook-第四版,由Packt发行

    本书涵盖以下激动人心的功能: 了解Node.js的异步和同步编程模型使用模块和Web框架创建简单的Node.js应用程序调试和诊断Node.js应用程序中的问题将Node.js应用程序部署到生产环境使用Fastify,Hapi和Express.js创建...

    Node.js-Web-Development-Fourth-Edition:Packt的Node.js Web开发第四版

    Node.js是一个服务器端JavaScript平台,使用事件驱动的非阻塞I / O模型,允许用户构建快速且可扩展的实时运行的事务密集型应用程序。 它在软件开发领域中发挥着重要作用,并从Web浏览器中释放了JavaScript。 借助...

    详解Node.js异步处理的各种写法

    异步的“坑” 最近一段时间参与开发了一个Node.js后台项目,作为一个PHP开发者,上手项目本身并不难,但是开发的过程却并不顺利,不顺利的主要原因在于...众所周知,Node.js采用的是单线程的异步模型,在具体代码的写

    Node.js开发第三方微信公众平台

      Node.js是一个开放源代码、跨平台的JavaScript语言运行环境,采用Google开发的V8运行代码,使用事件驱动、非阻塞和异步输入输出模型等技术来提高性能,可优化应用程序的传输量和规模。这些技术通常用于数据密集的...

    qianguyihao#Web#02-Node.js的特点1

    这是因为,Node.js 采用的是异步的、非阻塞的模型。使用 Node.js 时的劣势程序运行不稳定,可能会出现服务不可用的情况程序运行效率较低,每秒的请求数维

    深入浅析Node.js单线程模型

    Node.js采用 事件驱动 和 异步I/O 的方式,实现了一个单线程、高并发的运行时环境,而单线程就意味着同一时间只能做一件事,那么Node.js如何利用单线程来实现高并发和异步I/O?本文将围绕这个问题来探讨Node.js的单...

    深入浅析Node.js 事件循环

    Node.js 的每一个 API 都是异步的,并作为一个独立线程运行,使用异步函数调用,并处理并发。 Node.js 基本上所有的事件机制都是用设计模式中观察者模式实现。 Node.js 单线程类似进入一个while(true)的事件循环,...

    详解node.js 事件循环

    Node.js 是单进程单线程应用程序,但是因为 V8 引擎提供的异步...Node.js 使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。 当这个请求完成,它被放回处理队列,当到达

    极简MapReduce框架Mincemeat-node.zip

    Node.js的网络异步处理模型非常适合于这种突发通信量较大,性能要求比较高的场景,并且也是单文件随处运行的典型。相对的,Node.js也有一个 很严重的缺点:无法很好的利用多核CPU。因此在代码的实现上,我还是使用了...

    Node.js操作mongodb数据库

    Mongoose是MongoDB的一个对象模型工具,可以工作于异步环境下。具体学习内容参看官网http://mongoosejs.com/docs/index.html  1、开始运用mongoose时,得先安装,打开命令行,执行$ npm install mongoose  2、...

    我的Node.js学习之路(三)–node.js作用、回调、同步和异步代码 以及事件循环

    一,node.js的作用, I/O的意义,(I/O是输入/输出的简写,如:键盘敲入文本,输入,屏幕上看到文本显示输出。鼠标移动,在屏幕上看到鼠标的移动。...Node的事件化的I/O模型让我们无需担心互锁和并发这两个在多线程

    程序员面试刷题的书哪个好-Learning-Nodejs:学习Node.js

    程序员面试刷题的书哪个好 什么是node.js ...model非阻塞I/O模型(异步思想) lightweight and efficient轻量高效 “ Node.js package ecosystem, npm, is the largest ecosystem of open source libraries in

    深入理解Node.js 事件循环和回调函数

    本文详细的介绍了Node.js 事件循环和Node.js回调函数,废话不多说了,具体看下面把。  一、Node.js 事件循环 Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以...Node.js 使用事件驱动模型,当w

    nodejs-course:Node.JS简介和概述

    事件驱动Node.js使用带有事件循环的单线程模型,这就是为什么要强制采用异步编程风格的原因。阻塞与非阻塞 不好 :prohibited: // Blockingconst fs = require ( 'fs' ) ;const data = fs . readFileSync ( '/

    Vert.x线程模型揭秘

    其目的在于为JVM提供一个Node.js的替代方案。开发者可以通过它使用JavaScript、Ruby、Groovy、Java,甚至是混合语言来编写应用。使用Vertx.x框架,可以用JavaScript、CoffeeScript、Ruby、Python、Groovy或Java开发...

Global site tag (gtag.js) - Google Analytics