进程、线程与浏览器的那些事儿(一)

92 阅读5分钟

进程与线程

这是从网上找到的一张非常神似的图片

进程和线程是操作系统中的重要概念。

进程:是程序的一次执行过程,是系统进行资源分配和调度的基本单位。每个进程都有自己独立的地址空间、数据栈等。

线程:是进程中的一个执行流,是 CPU 调度的基本单位。线程共享进程的资源,如内存地址空间、文件描述符等,但每个线程有自己独立的程序计数器、栈等。线程之间可以并发执行,提高了程序的执行效率。如图

  • 并行是指多个任务同时执行
  • 并发是指一段时间内交替执行

深入了解的可以看看操作系统

(笔者也不理解)

线程通信主要有以下几种方式:

  1. 共享变量:线程通过访问共享的数据来进行通信。
  2. 信号量:用于控制对共享资源的访问。
  3. 互斥锁:保证同一时间只有一个线程能访问共享资源。
  4. 条件变量:线程可以等待特定条件的满足。
  5. 管道:用于在进程间或线程间传递数据。

进程通信的常见方式有以下几种:

  1. 管道:包括无名管道和命名管道,用于在具有亲缘关系的进程间传递数据。
  2. 消息队列:进程可以通过发送和接收消息来进行通信。
  3. 共享内存:多个进程可以共享同一块内存区域,直接进行数据交换。
  4. 信号:用于通知进程某个事件的发生。
  5. 套接字:可用于不同机器上的进程间通信。

浏览器有哪些进程

上图

注意:现代浏览器通常采用多进程架构,就是说一个 tab 标签就有以上几类进程

简单介绍一下概念

  1. Browser 进程(主进程) :只有一个,它负责浏览器界面的显示与交互,如控制浏览器的地址栏、书签栏、返回和前进按钮等;负责各个页面的管理,包括创建和销毁其他进程;进行网络资源的管理和下载等;还将Renderer 进程得到的内存中的位图绘制到用户界面上。
  2. 第三方插件进程:每种类型的插件对应一个进程,仅在使用该插件时才会创建,这样可以避免插件崩溃影响整个浏览器。
  3. GPU 进程:最多只有一个,用于进行 3D 绘制等操作。
  4. 浏览器渲染进程(内核进程) :默认情况下,每个 Tab 页面会对应一个独立的渲染进程。不过,浏览器也有优化机制,例如来自同一域名的多个空白 tab 可能会合并成一个进程。该进程内部是多线程的,主要负责页面渲染、脚本执行、事件处理等,其包含的线程主要有:
    • GUI 渲染线程:负责渲染浏览器界面,包括解析 HTML、构建 DOM 树、解析 CSS、构建 CSSOM 树、进行布局和绘制等。当界面需要重绘或由于某种操作引发回流时,该线程会执行相关操作。但它与 JS 引擎线程是互斥的,当 JS 引擎执行时,GUI 线程会被挂起,GUI 更新会被保存在一个队列中,等到 JS 引擎空闲时再立即执行。
    • JS 引擎线程:也称为 JS 内核,负责处理 Javascript 脚本程序,例如解析和执行代码等。一个 Tab 页面中无论何时都只有一个 JS 线程在运行 JS 程序。GUI 渲染线程和JS 引擎线程是互斥的,这两个都会使用到 dom,这也说明为什么 js 会阻塞页面渲染
    • 事件触发线程:归属于浏览器而非 JS 引擎,用于控制事件循环。当来自 JS 引擎线程(如执行setTimeout)或浏览器内核的其他线程(如鼠标点击、ajax 异步请求等)触发相应事件时,该线程会将事件对应的回调函数放入待处理队列(宏任务队列)中,等待 JS 引擎线程处理。
    • 定时触发器线程:setIntervalsetTimeout所在线程。由于 JavaScript 引擎是单线程的,如果处于阻塞线程状态会影响计时的准确,因此通过单独线程来计时并触发定时,计时完毕后,将事件添加到待处理队列(宏任务队列)中,等待 JS 引擎空闲后执行。需要注意的是,W3C 在 HTML 标准中规定,setTimeout中低于 4ms 的时间间隔会被算作 4ms。
    • 异步 HTTP 请求线程:当 XMLHttpRequest 连接后,浏览器会新开一个线程进行请求。当检测到状态变更时,如果设置有回调函数,异步线程会产生状态变更事件,并将回调函数放入事件队列(微任务队列)中,等待 JS 引擎执行。
  1. 网络进程:主要负责页面网络资源的加载,同一域名下会限制网络请求的并发数。

以上有几个问题需要看一下

  • 什么是事件循环?
  • 异步 HTTP 请求线程与网络进程的区别?
  • js会阻塞页面渲染,如何优化呢? async 与 defer 的区别?
  • 为什么同一域名下会限制网络请求的并发数?
  • 网页加载的全过程是什么?(需要了解 tcp 已经 http 协议等)