node的同步/异步/阻塞/非阻塞

1.node 是什么

node是JavaScript的一个运行环境

node底层使用c++实现

语法遵循ECMAScript

node中例如fs模块和Buffer是对ECMAScript的扩展

 

2.node内部机制

在cpu完成任务之前cpu任何情况下都不会暂停或者停止执行

cpu如何执行和同步或是异步,阻塞或是非阻塞都是没有必然关系

操作系统始终保证cpu处在运行状态,是通过调度来实现的,

具体一点就是通过在不同的进程和线程间切换实现的

 

3.回调是什么

回调值通过函数参数的参数传递到其他代码,某段可执行代码的引用

(简单说就是将一个函数作为参数传递给另一个函数,并且作为参数的函数可以被执行)

本质上是一个高阶函数

高阶函数: (1)接受一个或多个函数作为输入(2)输出一个函数

主程序调用->底层调用调用->回调函数

回调方法和主线程处于同一层级

***回调函数调用既可以是同步的例如map方法,也可以是异步的例如setTimeout中的异步回调

 

单线程语言例如php在完成i/o前会阻塞

而node遇到i/o 操作后会发起一个调用然后继续向下执行

等待i/o操做完成后再执行对应的回调函数,即异步

虽然在单线程的情况下依靠异步+回调的方式,也能实现对高并发的支持

 

4.同步/异步/阻塞/非阻塞

同步和异步描述的是进程/线程的调用方式

同步指进程/线程发起调用后 一直等到调用返回后才继续执行下一步的操作

这并不代表cpu在这一段时间内也会一直等待

操作系统会切换到另一个进程/线程上去

等到调用返回后再切换回原来的进程/线程

异步就是与之相反,发起调用后,进程/线程继续向下执行

当调用返回后,通过**某种手段**来通知调用者

注意:**同步异步中的调用返回**是指内核进程将数据复制到调用进程(linux环境下)

**javaScript的异步是依靠浏览器内部的runtime(解释器/运行环境)内部其他线程来实现的

并非JavaScript本身的功能,是浏览器让javaScript看起来像是一个异步的语言**

4.1阻塞/非阻塞

阻塞与非阻塞是针对i/o状态而言的

关注程序在等待i/o调用返回的这段时间的状态

阻塞/非阻塞 和 同步/异步 完全是两组概念

他们之间没有必然的联系

除了存粹的**AIO**之外阻塞和非阻塞i/o都是同步的

i/o即输入输出 是指在内存和外部设备(磁盘,终端,网络)之间复制数据的过程

********************************************

在node中i/o特指node程序在libuv支持下与系统磁盘和网络交互的过程

i/o调用的结果如何返回给调用的进程/线程

是通过内核进程复制给调用进程

linux下用户无法访问内核空间

通常采用copy_to_user方法来传递数据

 

大致流程就是i/o的数据会先被内核空间读取

然后内核将数据复制给用户进程

(零复制技术,内核进程和用户进程共享一块内存地址,这避免的内存的复制)

 

4.2 i/o编程模型

编程模型是指  操作系统在处理i/o时所 采用的方式

为了解决i/o 速度比较慢

编程模型有以下几种

1.阻塞i/o

2.非阻塞i/o 和阻塞i/o的区别是用户进程会不断查询内核的状态,这个过程是同步的

3.事件驱动i/o 以轮询的方式来查询内核的运行状态 

和非阻塞i/o 的区别是一个进程可能会管理多个i/o请求

注:select和poll都是i/o服用的机制

node使用epoll(改进后的poll)

4.异步i/o 当进程发出调用后,内核会立刻返回结果

进程会继续做其他的事情,知道操作系统返回数据

给用户进程发送一个信号

注意**************异步i/o并没有涉及任何关于回调函数的概念

这里的异步i/o只存在于linux系统下

node是真实的非阻塞而node中的异步i/o是依靠libuv模拟出来的

***************************************

总结:同步调用会造成调用进程的i/o阻塞

异步调用不会造成调用进程的阻塞

 

5.单线程多线程~~~~~~~~~~

node并没有提供多线程的支持

用于运行代码的事件循环也是单线程运行的

开发者无法在一个独立的进程中增加新的线程

但可以派生出多个进程来达到并行完成工作的目的

 

另一方面node的底层实现并非单线程

libuv会通过类似的线程池的实现来模拟不同操作系统下的异步操作

总结: 开发者的代码是运行在单线程环境中

因为libuv中是有线程池的概念存在

所以node都是依靠单线程运行的说法是错误的*******************

 

libuv是一个跨平台的异步i/o库

结合了unix下的libev和windows下的iopc的特性

专门为node提供多平台下的异步i/o支持

libuv是用c++实现的

node中的非阻塞i/o以及事件循环的底层机制都是由libuv来实现的

 

在windows环境下libuv使用iocp(i/o completion port)来实现异步i/o

在非windows环境下libuv使用多线程来模拟异步i/o

 

例如readFile 读取文件的系统室友libuv来完成的node只负责调用libuv的接口

等数据返回后再执行对应的回调方法

6.并发和并行

并发是希望计算机做更多的事情

并行是希望计算机能更快地完成任务

 

d单线程的高并发通常是依靠 异步+事件驱动(循环)来实现的

异步使得代码在面对多个请求时不会发生阻塞

事件循环提供了i/o调用结束后调用回调函数的能力

****************************

总结:除了你的代码一切都是并行的***************************

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值