一般来说,高并发的解决方案就是提供多线程模型,服务器为每个客户端请求分配一个线程,使用同步 I/O,系统通过线程切换来弥补同步 I/O
调用的时间开销。比如 Apache 就是这种策略,由于 I/O
一般都是耗时操作,因此这种策略很难实现高性能,但非常简单,可以实现复杂的交互逻辑。

而事实上,大多数网站的服务器端都不会做太多的计算,它们接收到请求以后,把请求交给其它服务来处理(比如读取数据库),然后等着结果返回,最后再把结果发给客户端。因此,Node.js
针对这一事实采用了单线程模型来处理,它不会为每个接入请求分配一个线程,而是用一个主线程处理所有的请求,然后对 I/O
操作进行异步处理,避开了创建、销毁线程以及在线程间切换所需的开销和复杂性。

那么在了解NodeJs异步非阻塞机制之前,你是否了解同步异步,阻塞和非阻塞?

同步与非同步:更面向非IO代码
阻塞与非阻塞:更面向IO代码

什么是同步机制?


同步就是必须等待上一个函数执行完毕,才能继续向下执行

什么是异步机制?


主线程执行到类IO操作时,会调用底层封装的libuv分配线程执行,并放入队列中等待主线程循环事件抽取,详细的后面会讲到

什么是阻塞机制?


顾名思义,必须等待前一个得到结果后才能继续执行,和同步容易混淆,但阻塞主要针对的是IO操作

什么是非阻塞机制?

非阻塞,意味着不用等待前一个IO操作返回就可以直接执行其他的IO操作

想必大家已经对这些概念有了一定了解,就让我们继续向下阅读

众所周知,JavaScript是单线程执行的,也就是说所有的非IO请求代码都会在主线程中同步执行,但是当我们发起IO请求时,该IO请求就不是在主线程中执行了,不然主线程就会被阻塞调,无法响应其他事件,看下图


NodeJs是异步IO调用,根据上图我们所得,当我们发起IO请求时,调用的是各个不同平台的操作系统内部实现的线程池内的线程,这里的IO请求不仅仅是读写文件,在unix中,将计算机抽象了一层,磁盘文件,硬件,套接字等几乎所有计算机资源都被抽象为文件,即IO请求就是抽象后的文件

NodeJs基于libuv的架构示意图:

什么是libuv?

Libuv是一个高性能的,事件驱动的异步I/O库,它本身是由C语言编写的,具有很高的可移植性。libuv封装了不同平台底层对于异步IO模型的实现,所以它还本身具备着Windows, Linux都可使用的跨平台能力。
https://juejin.im/post/5d412865e51d4561e84fcba7

什么是IOCP?

是windows支持多个同时发生的异步I/O操作的应用程序编程接口

根据上图所得,Node是基于libuv封装层运行来实现跨平台兼容的,所有平台兼容性的判断都由这一层来完成,并保证Node程序与unix和IOCP之间各自独立,Node在编译期间会判断平台条件,选择性编译unix目录或windows目录下的原文件到目录程序中。

具体异步IO实现图:

仔细查看上图我们发现:
构成NodeJs异步IO模型主要分四大要素

  • 事件循环
  • 观察者
  • 请求对象
  • IO线程池
           
    主线程操作
    发起异步IO调用,将请求参数(param, path, callback)等信息封装到请求对象上,然后将请求对象放入请求队列中,等待线程池给该请求分配可用线程
           
    线程池操作:
    如果线程池中有可用的线程,则取出请求队列内请求对象并分配线程,在分配的线程内执行对象中的IO操作,执行完成后将执行结果封装到请求对象中,通知线程池IO操作已经完成,然后将该线程还给线程池
           
    事件循环操作:
    底层使用了while(true)机制获取已完成IO操作的事件,并触发该事件,相对应的IO事件观察者会获取该请求对象(此时该请求对象已经涵盖了callback, param等),IO观察者取出callback和IO执行结果并调用执行函数callback

总结

Node.js 在主线程里维护了一个事件队列,当接到请求后,就将该请求作为一个事件放入这个队列中,然后继续接收其他请求。当主线程空闲时(没有请求接入时),就开始循环事件队列,检查队列中是否有要处理的事件,这时要分两种情况:如果是非 I/O 任务,就通过主线程处理,并通过回调函数返回到上层调用;如果是 I/O 任务,就从 线程池 中拿出一个线程来处理这个事件,并通过观察者指定回调函数,然后继续循环队列中的其他事件。
当线程中的 I/O 任务完成以后,通过观察者执行指定的回调函数,并把这个完成的事件放到事件队列的尾部,等待事件循环,当主线程再次循环到该事件时,就直接处理并返回给上层调用

参考文章:
https://juejin.im/post/5d412865e51d4561e84fcba7
https://www.cnblogs.com/onepixel/p/7143769.html
https://juejin.im/post/5d21f7e9e51d455071250b81
https://juejin.im/post/5af1413ef265da0b851cce80

NodeJs 异步非阻塞相关推荐

  1. 线程同步 阻塞 异步 非阻塞(转)

    同步:函数没有执行完不返回,线程被挂起 阻塞:没有收完数据函数不返回,线程也被挂起 异步:函数立即返回,通过事件或是信号通知调用者 非阻塞:函数立即返回,通过select通知调用者 这样看来异步和非阻 ...

  2. python3 异步 非阻塞 IO多路复用 select poll epoll 使用

    有许多封装好的异步非阻塞IO多路复用框架,底层在linux基于最新的epoll实现,为了更好的使用,了解其底层原理还是有必要的. 下面记录下分别基于Select/Poll/Epoll的echo ser ...

  3. 真正的 Tornado 异步非阻塞

    其中 Tornado 的定义是 Web 框架和异步网络库,其中他具备有异步非阻塞能力,能解决他两个框架请求阻塞的问题,在需要并发能力时候就应该使用 Tornado. 但是在实际使用过程中很容易把 To ...

  4. 处理大并发之一 对异步非阻塞的理解

    处理大并发之一 对异步非阻塞的理解 在研究nginx和node.js的时候常会遇到异步.非阻塞等,之前自己也经常使用epoll,对其同步与阻塞,异步与非阻塞有了一定的认识,现对参考资料总结下. 首先讨 ...

  5. 同步阻塞,同步非阻塞,异步阻塞,异步非阻塞IO

    在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作. 在比较这两个模式之前,我们首先的搞明白 ...

  6. 200行自定义异步非阻塞Web框架

    Python的Web框架中Tornado以异步非阻塞而闻名.本篇将使用200行代码完成一个微型异步非阻塞Web框架:Snow. 一.源码 本文基于非阻塞的Socket以及IO多路复用从而实现异步非阻塞 ...

  7. 同步阻塞、同步非阻塞、异步阻塞、异步非阻塞与 I/O 多路复用、Java NIO 之间的联系

    同步阻塞.同步非阻塞.异步阻塞.异步非阻塞与 I/O 多路复用.Java NIO 之间的联系 先验知识 此处的异步指的是什么 同步.异步.阻塞.非阻塞 同步阻塞.同步非阻塞.异步阻塞.异步非阻塞 一个 ...

  8. Nginx的异步非阻塞

    转载地址:https://blog.csdn.net/dutsoft/article/details/55224755 同步与异步 同步与异步的理解 同步与异步的重点在消息通知的方式上,也就是调用结果 ...

  9. 基于MFC的socket编程(异步非阻塞通信)

    对于许多初学者来说,网络通信程序的开发,普遍的一个现象就是觉得难以入手.许多概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等,初学者往往迷惑不清,只知其 ...

最新文章

  1. Func与Action
  2. httpClient post方法 解析json数据(向服务器传递,接受服务器传递)
  3. 設備(IE01/IE02/IE03)客製欄位及BAPI處理
  4. 多项式对数函数ln f(x)
  5. define定义的函数如何引用_C语言快速入门——使用#define让程序更易维护
  6. Layer2匿名交易协议ZKCHAOS与跨链资产桥ChainSwap合作促进跨链隐私保护
  7. javascript正则表达式验证IP,URL
  8. [HDU1003]最长子序列和
  9. MySQL-5.6.14-winx64的免安装配置方法
  10. 知识点收录04:MAVEN相关的知识点
  11. 高德地图 API 搜索服务 搜索定位 用不了
  12. Privoxy教程使用详解
  13. 2018 蓝桥杯 省赛 B组 原题 C语言B组 第二题 第九届蓝桥杯真题+答案+解析
  14. 用python获得图片定位信息
  15. vue3+vite+ts 通过svg-sprite-loader 插件使用自定义图标
  16. 优化PyTorch性能的一些trick
  17. Java实现 蓝桥杯VIP 算法提高 洗牌
  18. html5脑图_基于HTML5的三维思维导图软件开发技术研究
  19. 微信小程序界面及硬件实物图
  20. ubuntu安装显卡驱动和cuda

热门文章

  1. qpython op怎么用_QPython OPAPP推广手机版下载
  2. android 喇叭帧动画,Android动画详解-帧动画
  3. 如何给clion、pycharm等JetBrains IDE换背景
  4. 【Linux】正则表达式与文本搜索
  5. cad命令栏还原默认_怎么把cad2014恢复默认设置(怎么讲CAD快捷键还原为默认模式?)...
  6. 上班一个月,我的几点体会
  7. Nature全球潮汐可视化兼影像数据下载网站:Intertidal change
  8. vue使用高德地图实现多车定位和信息窗口:
  9. ionic5+angular 中 modal的ngIf报错,同时解决ngx-img-cropper组件无法显示图片的问题
  10. office 提示 关闭_什么是Office智能服务,您应该关闭它们吗?