进程线程回顾
文章目录
- 前言
- 进程和线程的联系和区别
- Chrome打开一个页面有多少进程?
- 渲染进程中的线程
- 进程间的通信方式
- 多标签之间怎么通信?
前言
之前在学习进程和线程的时候,只知道一个进程可以有多个线程,每个进程之间是独立的,一个进程的多个线程之间资源是共享的,我对进程和线程的了解仅限于此,最近复习到网络部分的知识,才发现我对进程和线程的理解非常浅显,借此回顾一下
进程和线程的联系和区别
当启动某个程序后,操作系统会给该程序创建一块内存,用来存放代码,运行中的数据和一个执行任务的主线程,这样的一个运行环境就叫进程
而线程是依附于进程的,在进程中使用多线程并行处理能提升运算效率,进程将任务分成很多细小的任务,再创建多个线程,在里面并行分别执行
进程和线程的关系特点是这样的
- 进程与进程之间需要传递某些数据的话,就需要通过
进程通信管道IPC
(共享进程最快的方式)来传递 - 进程与进程之间完全隔离,互不干扰,一个进程的崩溃并不会影响其他进程,避免一个进程出错影响整个程序
- 一个进程中可以并发多个线程,每个线程并行执行不同的任务
- 一个进程中的任意一个线程执行出错,会导致这个进程崩溃
- 同一进程下的线程之间可以直接通信和共享数据
- 当一个进程关闭之后,操作系统会回收该进程的内存空间
早期浏览器 2007年之前的浏览器并不是多进程的结构,而是单进程的结构,一个进程中包含了网络,js运行环境,渲染引擎,页面,插件,这也导致了很多问题
- 不稳定 :一个线程卡死,整个程序都会出问题,比如一个标签页卡死可能整个浏览器崩溃
- 不安全 :浏览器一个进程里是可以共享数据的,那js线程就可以随意访问各个标签页的数据,不合理
- 不流畅 :一个进程要负责的太多事情,会导致运行效率问题
Chrome打开一个页面有多少进程?
1个浏览器进程
1个GPU进程
1个网络进程
多个渲染进程
多个插件进程
浏览器进程
:负责控制浏览器除了标签页以外的界面,包括地址栏,书签,前进后退 以及负责与其他进程的协调工作 同时提供存储功能GPU进程
: 负责整个浏览器界面的渲染
谷歌一开始没有GPU进程,而使用GPU进程的初衷是为了实现3D CSS的效果 只是后面网页 谷歌的UI界面都用GPU来绘制,使得GPU成为浏览器普遍的需求 最后Chorme在多进程架构上也引入了GPU进程
网络进程
:负责发起网络请求插件进程
:负责插件运行 因为插件可能会崩溃 为了不影响其他进程导致其他进程崩溃,因此独立出来,成为一个单独进程渲染进程
:负责控制显示tab标签页的所有内容 核心任务是将HTML CSS JS转为用户可以与之交互的网页 排版引擎Blink 和JS引擎V8都是运行在该进程中,默认情况下Chrome会为每个tab标签页创建一个渲染进程
GPU进程和渲染进程都是负责渲染方面的 那么有什么区别?
可以把 GPU 进程想象成一个大工厂的管理者,而渲染进程是工厂里负责具体生产的工人
GPU服务整个系统,为多个应用程序分配GPU资源
渲染进程常与特定应用和窗口绑定,各渲染进程独立工作
渲染进程中的线程
- GUI渲染线程:负责渲染页面 解析html和CSS,构建DOM树,CSSOM树
- JS引擎线程:一个tab页中只有一个JS引擎线程(单线程),负责解析和执行JS。它GUI渲染进程不能同时执行,只能一个一个来,如果JS执行过长就会导致阻塞掉帧
- 计时器线程:指setInterval和setTimeout,因为JS引擎是单线程的,所以如果处于阻塞状态,那么计时器就会不准了,所以需要单独的线程来负责计时器工作
- 异步http请求线程: XMLHttpRequest连接后浏览器开的一个线程,比如请求有回调函数,异步线程就会将回调函数加入事件队列,等待JS引擎空闲执行
- 事件触发线程:主要用来控制事件循环,比如JS执行遇到计时器,AJAX异步请求等,就会将对应任务添加到事件触发线程中,在对应事件符合触发条件触发时,就把事件添加到待处理队列的队尾,等JS引擎处理
进程间的通信方式
- 管道通信(IPC):就是操作系统在内核中开辟一段缓冲区,进程1可以将需要交互的数据拷贝到这个缓冲区里,进程2就可以读取了
- 消息队列通信:消息队列就是用户可以添加和读取消息的列表,消息队列里提供了一种从一个进程向另一个进程发送数据块的方法,不过和管道通信一样每个数据块有最大长度限制
- 共享内存通信:就是映射一段能被其他进程访问的内存,由一个进程创建,但多个进程都可以访问,共享进程最快的是IPC方式
- 信号量通信:比如信号量初始值是1,进程1来访问一块内存的时候,就把信号量设为0,然后进程2也来访问的时候看到信号量为0,就知道有其他进程在访问了,就不访问了
- socket:其他的都是同一台主机之间的进程通信,而在不同主机的进程通信就要用到socket的通信方式了,比如发起http请求,服务器返回数据
多标签之间怎么通信?
没有办法直接通信,需要有一个类似中介者进行消息的转发和接收,比如
localStorage
:在一个标签页监听localStorage的变化,然后当另一个标签页修改的时候,可以通过监听获取新数据WebSocket
:因为websocket可以实现实时服务器推送,所以服务器就可以来当这个中介者。标签页通过向服务器发送数据,然后服务器再向其他标签推送转发ShareWorker
:会在页面的生命周期内创建一个唯一的线程,并开启多个页面也只会使用同一个线程,标签页共享一个线程postMessage
:
//发送方
window.parent().pastMessage('发送的数据','http://接收的址')
// 接收方
window.addEventListener('message',(e)=>{ let data = e.data })