1. 进程、线程和协程
进程 | 进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。 |
---|---|
线程 | 线程是进程中的一个实体,是被系统独立调度和分派的基本单位 ,分为主线程和子线程(主线程的优先级要绝对大于子线程) |
协程 | 协程是一种比线程更加轻量级的一种函数 正如一个进程可以拥有多个线程一样,一个线程可以拥有多个协程。 |
三者的不同 :
- 协程既不是进程也不是线程,协程仅是一个特殊的函数。协程、进程和线程不是一个维度的。
- 一个进程可以包含多个线程,一个线程可以包含多个协程。虽然一个线程内的多个协程可以切换但是这多个协程是串行执行的,某个时刻只能有一个线程在运行,没法利用CPU的多核能力。
- 协程与进程一样,也存在上下文切换问题。
- 进程的切换者是操作系统,切换时机是根据操作系统自己的切换策略来决定的,用户是无感的。进程的切换内容包括页全局目录、内核栈和硬件上下文,切换内容被保存在内存中。 进程切换过程采用的是“从用户态到内核态再到用户态”的方式,切换效率低。
- 线程的切换者是操作系统,切换时机是根据操作系统自己的切换策略来决定的,用户是无感的。线程的切换内容包括内核栈和硬件上下文。线程切换内容被保存在内核栈中。线程切换过程采用的是“从用户态到内核态再到用户态”的方式,切换效率中等。
- 协程的切换者是用户(编程者或应用程序),切换时机是用户自己的程序来决定的。协程的切换内容是硬件上下文,切换内存被保存在用自己的变量(用户栈或堆)中。协程的切换过程只有用户态(即没有陷入内核态),因此切换效率高。
2. 同步任务和异步任务
js 属于一种单线程语言,但是它可以处理不同的异步请求,原因就是在于
在js执行任务时会产生两种任务,就是 同步任务 和 异步任务
- 同步任务 : 读取之后,依次从上到下,从左到右进行执行
- 声明语句
- for()
- 赋值
- 异步任务 : 通过任务队列机制,(先进先出原则),进行协调
- ajax 网络请求
- setTimeout定时函数
3. 任务队列
在任务队列中分成两种 : 宏队列 和 微队列
-
宏队列 : 每次执行栈执行的代码 (包括每次从事件队列中获取一个事件回调并放到执行栈中执行)
-
微队列 : 在当前 task 执行结束后立即执行的任务
宏队列和微队列主要包括的内容 :
宏队列 微队列 script(整体代码) Promise.then setTimeout Object.observe setInterval MutationObserver I/O process.nextTick(Node.js 环境) UI交互事件 postMessage MessageChannel setImmediate(Node.js 环境)
任务队列的执行过程 :
- 先执行一个宏任务
- 执行过程中如果产出新的宏/微任务,就将他们推入相应的任务队列 - 然后执行同一层宏任务里面的微任务,有几个微任务就执行几个 (同层)
- 之后再执行宏任务
代码理解
为了更加方便的理解,直接在代码中注释
Promise 的执行
//子线程,放到最后输出
setTimeout(()=>{
console.log(0