2、进程和线程
进程(process)程序运行的实例,同一个程序可以产生多个进程,一个进程包含一个或多个线程
线程(thread)是操作系统能够进行运算调度的最小单位。每个线程一次只能执行一个任务。大部分情况下,它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。同一进程中的多条线程将共享该进程中的全部系统资源。但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。
进程和线程的区别和关系
进程是操作系统分配资源的最小单位,线程是程序执行的最小单位。
一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线;
进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号)。
调度和切换:线程上下文切换比进程上下文切换要快得多。
推荐阅读:
进程与线程的一个简单解释 - 阮一峰的网络日志https://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html
linux查看进程的命令:ps(process status)、top (table of processes)
3、JS单线程
JS单线程:方便简单的保证dom操作的一致性。
JS单线程的问题:一次执行一个任务,任务会排队,阻塞,影响用户体验,要想办法实现非阻塞。利用浏览器的多线程执行耗时任务
JS单线程怎么实现异步?
通过浏览器内核多线程实现异步。
GUI渲染线程负责渲染页面,布局和绘制。页面需要重绘和回流时,该线程就会执行,与js引擎线程互斥,防止渲染结果不可预期。
JS引擎线程负责处理解析和执行javascript脚本程序。只有一个JS引擎线程(单线程),与GUI渲染线程互斥,防止渲染结果不可预期。chrome的V8就是一个JS引擎。
定时触发器线程setInterval与setTimeout所在的线程。定时任务并不是由JS引擎计时的,是由定时触发线程来计时的。计时完毕后,通知事件触发线程。
事件触发线程用来控制事件循环(鼠标点击、setTimeout、ajax等)。当事件满足触发条件时,将事件放入到JS引擎所在的执行队列中。
异步http请求线程浏览器有一个单独的线程用于处理AJAX请求。当请求完成时,若有回调函数,通知事件触发线程。
浏览器采用多进程架构有什么优势和劣势?
优势:
(1)安全:可以使用安全沙箱,插件进程和渲染进程锁在沙箱里面,即使在渲染进程或者插件进程里面执行了恶意程序,恶意程序也无法突破沙箱去获取系统权限;进程隔离可以防止一个进程访问另一个进程的内存(要通信需要使用IPC【Inter Process Communication 】方式通信 ),提高了浏览器的安全性。
(2)稳定:多进程间相互隔离,在一个渲染引擎中的崩溃并不会影响浏览器本身或是其他网络应用,确保不会因为一个线程的崩溃导致整个浏览器崩溃。
(3)性能:多线程并行处理,执行速度更快
劣势:内存消耗大,系统为浏览器新开的进程分配内存、CPU 等资源,所以内存和 CPU 的资源消耗也会更大。
异步场景:定时器、网络请求、事件绑定、ES6 Promise
4、定时器
WebAPIs 本身并不能直接将回调函数放在函数调用栈中来执行,否则它会随机在整个程序的运行过程中出现。每个 WebAPIs 会在其执行完毕的时候将回调函数推入到对应的任务队列中,然后由 event loop 按照规则在函数调用栈为空的时候将回调函数推入执行栈中执行。
event loop 的基本作用就是检查函数调用栈和任务队列,并在函数调用栈为空时将任务队列中的的第一个任务推入执行栈中,每一个任务都在下一个任务执行前执行完毕。
注意:定时任务可能不会按时执行,要等同步任务执行完才能执行定时任务;定时器嵌套5次之后最小间隔不能低于4ms
定时器应用场景:防抖、节流、倒计时、动画(存在丢帧的问题)
为什么不建议采用定时器实现动画?requestAnimationFrame有哪些优势?
定时器的回调不能保证按照指定时间之后调用,只是会按照指定时间把动画代码插入到浏览器UI线程队列中,要等待UI线程空闲才会被调用所以不能保证是在渲染的每帧开始的时候执行动画 也就可能出现跳帧。 requestAnimationFrame就是为了解决这个问题的。
requestAnimationFrame采用系统时间间隔,保持最佳绘制效率,不会因为间隔时间过短,造成过度绘制,增加开销;也不会因为间隔时间太长,使用动画卡顿不流畅,让各种网页动画效果能够有一个统一的刷新机制,从而节省系统资源,改善视觉效果。