惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
Google Developers Blog
Spread Privacy
Spread Privacy
V
Visual Studio Blog
爱范儿
爱范儿
Apple Machine Learning Research
Apple Machine Learning Research
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
GbyAI
GbyAI
Google DeepMind News
Google DeepMind News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
V2EX
J
Java Code Geeks
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Blog — PlanetScale
Blog — PlanetScale
N
Netflix TechBlog - Medium
B
Blog RSS Feed
博客园 - 【当耐特】
有赞技术团队
有赞技术团队
The Register - Security
The Register - Security
Latest news
Latest news
The Cloudflare Blog
Project Zero
Project Zero
月光博客
月光博客
U
Unit 42
Vercel News
Vercel News
Attack and Defense Labs
Attack and Defense Labs
Know Your Adversary
Know Your Adversary
V
Vulnerabilities – Threatpost
F
Full Disclosure
Schneier on Security
Schneier on Security
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
L
Lohrmann on Cybersecurity
C
CERT Recently Published Vulnerability Notes
博客园 - 叶小钗
腾讯CDC
博客园 - 三生石上(FineUI控件)
T
The Blog of Author Tim Ferriss
D
Darknet – Hacking Tools, Hacker News & Cyber Security
博客园 - Franky
S
Security Affairs
Hacker News: Ask HN
Hacker News: Ask HN
Security Latest
Security Latest
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
MongoDB | Blog
MongoDB | Blog
D
DataBreaches.Net
SecWiki News
SecWiki News
Recorded Future
Recorded Future
NISL@THU
NISL@THU
Hacker News - Newest:
Hacker News - Newest: "LLM"
Cloudbric
Cloudbric

MARKSZのBlog

一次由 pnpm 小版本差异引发的 PicGo 2.5.3 发布事故 极空间虚拟机安装 Ubuntu 24.04 踩坑记录 | MARKSZのBlog PicGo 的签名与公证 | MARKSZのBlog 写在 PicGo 即将 8 周年之际 Vite 原理浅析 | MARKSZのBlog Typora 支持 PicGo 来上传图片了 | MARKSZのBlog 用setTimeout和clearTimeout简单实现setInterval与clearInterval | MARKSZのBlog 我的2019春招(暑期实习)记录 | MARKSZのBlog Electron-vue开发实战7——命令行调用与系统级别右键菜单的实现 | MARKSZのBlog Electron-vue开发实战6——开发插件系统之GUI部分 | MARKSZのBlog Electron-vue开发实战5——开发插件系统之CLI部分 | MARKSZのBlog 2018小结 | MARKSZのBlog 图床「神器」PicGo v2.0更新,插件系统终于来了 | MARKSZのBlog 一周一部好电影V【WEEK210 网络迷踪】 | MARKSZのBlog PicGo的star数破1000的心路历程 | MARKSZのBlog 小记VSCode插件amVim的改进以及插件开发 | MARKSZのBlog 基于Koa2开发微信二维码扫码支付相关流程 | MARKSZのBlog 【NOTE】观察者模式VS订阅发布模式 | MARKSZのBlog 基于Electron-vue的图床上传工具PicGo v1.5更新说明 | MARKSZのBlog
【NOTE】进程-线程-协程 关系与区别 | MARKSZのBlog
Molunerfinn · 2018-05-12 · via MARKSZのBlog

在平时总会听到「进程」、「线程」,甚至最近由于Golang的火热我还听到了「协程」。但是平时我对这三个概念并不能很好的理解,甚至不知它们之间的区别和联系。所以专门找了时间了解了一下它们。本文仅为个人笔记,如有错误或者侵权行为请及时在下方评论里指出!感谢。

进程

一个进程好比是一个程序,它是 资源分配的最小单位 。同一时刻执行的进程数不会超过核心数。不过如果问单核CPU能否运行多进程?答案又是肯定的。单核CPU也可以运行多进程,只不过不是同时的,而是极快地在进程间来回切换实现的多进程。举个简单的例子,就算是十年前的单核CPU的电脑,也可以聊QQ的同时看视频。

电脑中有许多进程需要处于「同时」开启的状态,而利用CPU在进程间的快速切换,可以实现「同时」运行多个程序。而进程切换则意味着需要保留进程切换前的状态,以备切换回去的时候能够继续接着工作。所以进程拥有自己的地址空间,全局变量,文件描述符,各种硬件等等资源。操作系统通过调度CPU去执行进程的记录、回复、切换等等。

线程

如果说进程和进程之间相当于程序与程序之间的关系,那么线程与线程之间就相当于程序内的任务和任务之间的关系。所以线程是依赖于进程的,也称为 「微进程」 。它是 程序执行过程中的最小单元

一个程序内包含了多种任务。打个比方,用播放器看视频的时候,视频输出的画面和声音可以认为是两种任务。当你拖动进度条的时候又触发了另外一种任务。拖动进度条会导致画面和声音都发生变化,如果进程里没有线程的话,那么可能发生的情况就是:

拖动进度条->画面更新->声音更新。你会明显感到画面和声音和进度条不同步。

但是加上了线程之后,线程能够共享进程的大部分资源,并参与CPU的调度。意味着它能够在进程间进行切换,实现「并发」,从而反馈到使用上就是拖动进度条的同时,画面和声音都同步了。所以我们经常能听到的一个词是「多线程」,就是把一个程序分成多个任务去跑,让任务更快处理。不过线程和线程之间由于某些资源是独占的,会导致锁的问题。例如Python的GIL多线程锁。

协程

协程在线程中实现调度。你可以理解为它是 「微线程」 。它的调度不来自于CPU,而是完全来自于用户控制(可以理解为用代码控制流程)。协程的执行效率非常高,它的切换不是线程切换,没有线程切换的开销。而且只要线程越多,协程的性能优势就越明显。协程不需要多线程的锁机制,只需要判断状态即可。不过协程本身无法利用多核CPU,因为它基于线程,而线程又依赖于进程。

在JS里,常见的协程就是ES6的yield Generator或者ES7的async await。我们知道JS引擎是单线程的。所以在处理异步任务队列的时候,以往我们会陷入「回调金字塔」或者「回调地狱」。而有了协程之后我们可以在代码层面上来控制我们的程序。

比如我们有这么一个需求,等两个请求都返回之后,用它们的返回值共同做些事。(此处不用Promise.all()来实现,不是说不行,而是为了更好地说明主题)

ES6 + co 的写法:

1
2
3
4
5
6
7
const axios = require('axios')
const co = require('co')
co(function* (){
const getData = yield axios.get('xxx')
const postData = yield axios.post('xxx')
console.log(getData, postData)
})

ES7 的写法:

1
2
3
4
5
6
const axios = require('axios')
(async function () {
const getData = await axios.get('xxx')
const postData = await axios.post('xxx')
console.log(getData, postData)
})()

上述用「同步」的方式写的代码实际上依然是异步执行的。不过因为了有协程,在单线程的JS里也能够让我们在代码层面上实现了任务调度。

总结

可以说三者虽然是不同的东西,但是有着很密切的关系和类似的特性。它们的关系是从大到小,从上而下的。没有进程也就没有线程也就没有协程。总的来说,在多核处理器的情况下,多进程+多协程可以发挥最优的性能。

参考文献

  1. 进程,线程,协程与并行,并发
  2. 进程和线程、协程的区别
  3. 进程、线程和协程的比较
  4. 线程、进程与处理器

Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.