进程与线程
这是从网上找到的一张非常神似的图片
进程和线程是操作系统中的重要概念。
进程:是程序的一次执行过程,是系统进行资源分配和调度的基本单位。每个进程都有自己独立的地址空间、数据栈等。
线程:是进程中的一个执行流,是 CPU 调度的基本单位。线程共享进程的资源,如内存地址空间、文件描述符等,但每个线程有自己独立的程序计数器、栈等。线程之间可以并发执行,提高了程序的执行效率。如图
- 并行是指多个任务同时执行
- 并发是指一段时间内交替执行
深入了解的可以看看操作系统
(笔者也不理解)
线程通信主要有以下几种方式:
- 共享变量:线程通过访问共享的数据来进行通信。
- 信号量:用于控制对共享资源的访问。
- 互斥锁:保证同一时间只有一个线程能访问共享资源。
- 条件变量:线程可以等待特定条件的满足。
- 管道:用于在进程间或线程间传递数据。
进程通信的常见方式有以下几种:
- 管道:包括无名管道和命名管道,用于在具有亲缘关系的进程间传递数据。
- 消息队列:进程可以通过发送和接收消息来进行通信。
- 共享内存:多个进程可以共享同一块内存区域,直接进行数据交换。
- 信号:用于通知进程某个事件的发生。
- 套接字:可用于不同机器上的进程间通信。
浏览器有哪些进程
上图
注意:现代浏览器通常采用多进程架构,就是说一个 tab 标签就有以上几类进程
简单介绍一下概念
- Browser 进程(主进程) :只有一个,它负责浏览器界面的显示与交互,如控制浏览器的地址栏、书签栏、返回和前进按钮等;负责各个页面的管理,包括创建和销毁其他进程;进行网络资源的管理和下载等;还将Renderer 进程得到的内存中的位图绘制到用户界面上。
- 第三方插件进程:每种类型的插件对应一个进程,仅在使用该插件时才会创建,这样可以避免插件崩溃影响整个浏览器。
- GPU 进程:最多只有一个,用于进行 3D 绘制等操作。
- 浏览器渲染进程(内核进程) :默认情况下,每个 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 引擎线程处理。 - 定时触发器线程:
setInterval与setTimeout所在线程。由于 JavaScript 引擎是单线程的,如果处于阻塞线程状态会影响计时的准确,因此通过单独线程来计时并触发定时,计时完毕后,将事件添加到待处理队列(宏任务队列)中,等待 JS 引擎空闲后执行。需要注意的是,W3C 在 HTML 标准中规定,setTimeout中低于 4ms 的时间间隔会被算作 4ms。 - 异步 HTTP 请求线程:当 XMLHttpRequest 连接后,浏览器会新开一个线程进行请求。当检测到状态变更时,如果设置有回调函数,异步线程会产生状态变更事件,并将回调函数放入事件队列(微任务队列)中,等待 JS 引擎执行。
- 网络进程:主要负责页面网络资源的加载,同一域名下会限制网络请求的并发数。
以上有几个问题需要看一下
- 什么是事件循环?
- 异步 HTTP 请求线程与网络进程的区别?
- js会阻塞页面渲染,如何优化呢? async 与 defer 的区别?
- 为什么同一域名下会限制网络请求的并发数?
- 网页加载的全过程是什么?(需要了解 tcp 已经 http 协议等)