这是我参与更文挑战的第7天,活动详情查看:更文挑战
基本概念
CPU(Central Processing Unit)
CPU是计算机的一块芯片,也是计算机的大脑,目前流行的主要是多核的CPU。理论上单核的CPU只能串行地一件一件处理任务,但事实上可以是多个任务交替执行,看上去也达到了多任务并行的效果。
打个比方,CPU就像一间办公室,而每个核心就像每个工位上的人,各自处理自己的任务。
GPU(Graphics Processing Unit)
GPU顾名思义,主要是用来处理图形的,它的特点是,单个核心可以处理的任务比较简单,但胜在数量众多。
打个比方,就像只会拧螺丝的工人,但人多力量大。
进程(process)与线程(thread)
CPU 要处理的任务,就是进程。每启动一个程序,操作系统就会为它添加一个进程,并且分配相应的内存空间。而每个进程里要处理的子任务就是线程,一个进程里可以包含很多的线程。
进程之间是相互独立的,不同的进程可以通过IPC(Inter Process Communication)
来通信。
同一个进程下的不同线程,可以共享该程序的内存空间(包括代码段、数据集等)和资源(比如打开文件、信号等)。
Chrome浏览器采用多进程模式
根据上面的概念,可以知道一个多任务的应用程序,可以采用以下几种方法来处理:
- 单进程多线程
- 多进程单线程
- 多进程多线程
不同的程序可能会有不同的方案,但以Chrome浏览器为例,它采用的是多进程多线程的模式。
多进程的优点
- 更稳定: 避免单个网页崩溃其他页面也会受影响、避免第三方插件崩溃影响整个浏览器
- 更快: 多进程可以充分利用多核优势
- 更安全: 进程之间不会共享资源和空间,避免恶意修改或者获取非授权数据等安全问题
进程类型
Chrome的进程,一般分为以下几种类型:
Browser(浏览器进程)
浏览器主进程,用于管理tab页、窗口和浏览器本身。这个进程同时负责处理所有跟磁盘、网络、用户输入和显示的交互,不会分析和渲染任何网页内容。它包括的线程有:
- 绘制浏览器顶部按钮和导航栏输入框等组件的UI线程(
UI thread
) - 管理网络请求的网络线程(
network thread
) - 以及控制文件读写的存储线程(
storage thread
) - ……
Plugin(第三方插件进程)
浏览器进程同样为处于使用状态的每种类型的插件创建一个进程,如:Flash、Quicktime 等。这些进程仅仅包含插件本身以及和浏览器进程、渲染器进程交互的胶水代码。
GPU进程
最多一个,用于 3D 绘制等。
Renderer(浏览器渲染进程)
用于渲染tab页,负责页面展示。这个进程会存在多个,对磁盘、网络和显示器没有直接的访问权限,必须通过浏览器进程来处理相关系统交互。
Renderer进程又包括了以下线程:
1. GUI渲染线程
负责渲染浏览器界面元素,界面需要重绘(Repaint)或回流(reflow)时执行,与JS引擎互斥。
2.JavaScript引擎线程
JS内核,例如V8引擎,负责处理JavaScript脚本程序。这里可以看出,JavaScript是单线程的。
JavaScript语言本身设计为单线程,是考虑到多线程可能操作同一个UI DOM,会导致一些临界问题,需要更复杂的方式来处理冲突,因此JavaScript最初的设计就选择了单线程执行。
3. 定时器触发线程
JS引擎为单线程,阻塞线程状态会影响计时器准确性,所以由单独线程来管理定时器
4. 事件触发线程
事件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎处理
5. 异步HTTP请求线程
异步请求会新开一个线程请求,获取回调之后放入JS引擎的处理队列
线程之间的关系
- GUI渲染引擎与JavaScript引擎互斥,为了避免渲染出现不可预期的结果,JS执行的时候,GUI线程就会挂起,GUI需要更新的时候会保存在一个队列,等到JS引擎线程空闲时再执行;
- JS执行时间过长会阻塞页面加载,会造成页面渲染不连贯,感觉到很卡。