大家很早就知道 JS 是一门单线程的语言. 但是也时不时的会看到进程这个词. 首先简单区分下线程和进程的概念
1. 简单理解进程
- 进程是一个工厂, 工厂有它的独立资源
- 工厂之间相互独立
- 线程是工厂中的工人, 多个工人协作完成任务
- 工厂内有一个或多个工人
- 工人之间共享空间
2. 简单理解线程
- 工厂的资源 -> 系统分配的内存(独立的一块内存)
- 工厂之间的相互独立 -> 进程之间相互独立
- 多个工人协作完成任务 -> 多个线程在进程中协作完成任务
- 工厂内有一个或多个工人 -> 一个进程由一个或多个线程组成
- 工人之间共享空间 -> 同一进程下的各个线程之间共享程序的内存空间(包括代码段, 数据集, 堆等)
3. 浏览器是多进程的
上面的 1.1 和 1.2 可能还是有些抽象. 接下来用与前端息息相关的浏览器为例展开.
当你打开浏览器开了好几个网页的时候, 打开浏览器的任务管理器(比如谷歌浏览器 -> 更多工具 -> 任务管理器)
这里就是查看进程的地方, 而且可以看到每个进程的 CPU 占用率和内存资源信息.
简单用比较官方的术语总结下:
进程是 CPU 资源分配的最小单位(是能拥有资源和独立运行的最小单位)
线程是 CPU 调度的最小单位(线程是建立在进程的基础上的一次程序运行单位, 一个进程中可以有多个线程)
不同进程之间也可以通信.(比如网页是一个进程, qq 是一个进程, 在网页上使用快捷方式 qq 登录. 网页怎么会知道你当前有没有登录 qq 的? 这之间就涉及到了不同进程之间的通信)
一般讨论的单线程和多线程, 都只是指在一个进程内的单和多.
4 浏览器是如何渲染进程的? 与 JS 的单线程有什么联系?
在浏览器中打开一个网页相当于新起了一个进程, 每个进程内又会有自己的多线程(当然, 浏览器有自身的优化机制, 当你开了很多空的标签页的时候, 可能会发现多个空白标签页被合并成了一个进程). 比如页面的渲染, JS 的执行, 事件的循环, 都会在这个进程内进行.(以下用比较官方的术语列举一些主要常驻线程)
扩散思考 1: 浏览器为什么要弄成多进程的?
优点:
避免单个标签页崩溃影响整个浏览器
避免第三方插件崩溃影响整个浏览器
多进程充分利用多核优势
方便使用沙盒模型隔离插件等进程, 提高浏览器稳定性
缺点:
会占用更多的内存
4.1. GUI 渲染线程
负责渲染浏览器界面, 解析 html,CSS, 构建 DOM 树和 RenderObject 树, 布局和绘制等.
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- Document
- </title>
- <style>
- .a { width: 100px; height: 100px; background: #f60; }
- </style>
- <script>
- console.time('js 执行') for (var i = 0; i < 1000000000; i++) {}
- console.timeEnd('js 执行')
- </script>
- </head>
- <body>
- <div class="a">
- a
- </div>
- </body>
- </HTML>
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <title>
- Document
- </title>
- </head>
- <body>
- <script>
- setTimeout(function() {
- console.log(1);
- }) new Promise(function(resolve) {
- console.log(2);
- for (var i = 0; i < 1000; i++) {
- i == 99 && resolve();
- }
- console.log(3);
- }).then(function() {
- console.log(4);
- }) console.log(5);
- </script>
- </body>
- </HTML>
来源: https://www.cnblogs.com/hezhi/p/10484884.html