该篇纯粹学习笔记。
学习资料
进程与线程
当启动一个程序时,操作系统就会给该程序创建一个内存空间(当程序被中止时,该内存空间就会被回收),该内存空间就是用来存放程序代码
,运行中的数据
和一个执行任务的主线程
,这样的一个运行环境(内存空间)就被称为进程。
而线程就是依附于进程的,进程将任务分为多个细小任务,分配给多个线程单独执行,可以提高运行效率。
进程与线程的特点:
- 进程与进程之间是完全隔离,独立运行。一个进程崩溃不会影响其他进程,避免一个进程出错影响整个程序。进程与进程之间的通信,代价较大,需要借助
进程通信管道 IPC
来传递。 - 一个进程包含多个线程,每个线程
并行
执行不同的任务。其中一个线程崩溃了,那么整个进程也就崩溃了。线程之间可以相互通信。
并行和并发的区别:
并发和并行都是操作系统的名词。
并发是一个人同时吃三个馒头(时间点是相互独立的,在一个时间点只能吃其中馒头的一口)
并行是三个人同时吃三个馒头(时间是重合的,三个人可以在同一时间吃馒头)
浏览器
浏览器是一个多进程架构设计,每打开一个标签页就会创建一个进程。当然浏览器内部也有着自己的优化,比如:当浏览器同时打开多个空白标签页的时候,会合并成一个进程。
浏览器到关闭到启动,至少开启四个进程:1个 browser进程
,1个GPU进程
,1个网络进程
,1个渲染进程
。
当新增其他标签页时,前面三个进程是可以共用的,不用重启。
默认情况下,每打开一个标签页,就会开启一个渲染进程。但是也会存在特殊的情况,就是如果打开的标签页在同一个站点下,会共享同一个渲染进程。
最新的浏览器进程主要包含:
- 1个浏览器主进程
- 1个GPU进程(也可能存在多个,每个标签页都需要一个进程,用于绘制图形)
- 1个网络进程
- 多个插件进程(每个插件都会开启一个进程,因为防止一个插件崩溃,造成整个浏览器崩溃)
- 多个渲染进程(标签页需要独立的进程)
browser 进程(主进程)
负责控制浏览器除标签页外的界面,包括地址栏、书签、前进后退按钮等,以及负责与其他进程的协调工作,同时提供存储功能。
GPU 进程
负责处理与图形渲染相关的任务。(着重在于图像)
- 图形渲染
- 动画和过渡
- 3D 和 WebGL 渲染
- 视频播放和解码等
网络进程
负责处理与网络相关的任务。它主要负责管理和维护网络连接,以及处理所有的网络请求和响应。
- 管理网络连接
- 处理网络请求和响应
- 处理DNS解析
- 处理缓存
- 处理安全问题
浏览器的网络进程和渲染进程的异步HTTP线程之间存在通信吗?
在浏览器中,当用户在页面上发起一个网络请求时,该请求首先由渲染进程中的异步 HTTP 线程发起,异步 HTTP 线程会将该请求通过 IPC 传递给网络进程。网络进程收到请求后,负责管理和维护网络连接,发送请求并接收响应,最后将响应数据再通过 IPC 传递给渲染进程中的异步 HTTP 线程处理。
在这个过程中,网络进程和渲染进程之间需要频繁地进行通信,以协同完成网络请求和响应的处理。例如,当请求被发送出去后,网络进程需要不断地监控连接状态和接收数据,并及时将收到的数据通过 IPC 传递给渲染进程中的异步 HTTP 线程,同时异步 HTTP 线程也需要不断地向网络进程查询请求状态和响应数据。 4 浏览器通过 IPC(进程间通信)机制来实现这种进程间通信,IPC 是浏览器中进程间交换数据的标准方法,其通信方式包括消息传递、共享内存、管道等。通过 IPC 机制,网络进程和渲染进程之间可以高效地传递数据和信息,保证了浏览器的正常工作和性能表现。
插件进程
用于处理浏览器插件的进程(每个插件,就会创建一个进程)
渲染进程
负责将 HTML、CSS 和 JavaScript 转换为可视化的页面。默认情况下,浏览器的tab就会创建一个渲染进程。
针对前端,需要着重了解该进程。
该进程包含:GUI 渲染线程
、JS 引擎线程
、定时触发线程
、异步 HTTP 线程
、事件触发线程
GUI 渲染线程
负责页面的渲染和绘制;解析 HTML和CSS,构建 DOM树、CSSOM树 、 渲染树(Render 树) ,布局和绘制等。重绘和重排也是发生在该线程中。
GUI 更新会被保存在一个队列之中,等到 JS 引擎线程空闲时,GUI 线程就会立即执行。
「GUI 线程和JS引擎线程是互斥的」
JS 引擎线程
也称为 JS 内核,负责处理 JavaScript 脚本程序。
再次注意,GUI 渲染线程与 JS 引擎线程是互斥的 ,所以,如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞。
定时触发线程
指的是计时函数:setInterval 和 setTimeout 两个函数。
由于 JS 引擎是单线程的,如果该线程处于堵塞状态,那么就会造成计时不准确,那么就需要单独一个线程来进行计时。
当计时完成之后,就会把事件回调(任务)添加事件队列中,等待 JS 引擎空闲后去执行。
异步 HTTP 线程
XMLHttpRequest 在连接后是通过浏览器新开的一个线程请求。
检测到状态发生变化之后,就会事件回调(任务)添加到事件队列中,等待 JS 引擎空闲后去执行。
事件触发线程
用来控制事件循环的(Event Loop)。
就比如上面的,
- 定时器的任务通过事件触发线程添加到事件队列中,
- 异步请求的任务是通过事件触发线程添加到事件队列中
- 。。。(收集任务)
事件触发线程还会周期性地检查事件队列中是否存在任务。当JS引擎线程空闲了,就会将其中的任务顺序交给 JS 引擎线程执行。
这里的解释可能存在错误。
事件触发线程是连接事件的发生和任务执行的桥梁。它负责接收事件,并将对应的任务添加到事件队列中,然后主动触发 JavaScript 引擎线程来执行任务。
存储线程
负责处理浏览器的各种存储机制,包括 cookie、localStorage、indexedDB 等。