网易首页 > 网易号 > 正文 申请入驻

带你通俗易懂了解进程、线程和协程

0
分享至


作者:肖玮

本故事采用简洁明了的对话方式,尽洪荒之力让你在轻松无负担的氛围中,稍微深入地理解进程、线程和协程的相关原理知识
写在最前

本故事采用简洁明了的对话方式,尽洪荒之力让你在轻松无负担的氛围中,稍微深入地理解进程、线程和协程的相关原理知识

如果你觉得自己本来就已经理解得很透彻了,那也不妨瞧一瞧,指不定有意外的收获呢

在这个 AI 内容生成泛滥的时代,依然有一批人"傻傻"坚持原创,如果您能读到最后,还请点赞或收藏或关注支持下我呗,感谢 ( ̄︶ ̄)↗
进程

丹尼尔:蛋兄,我对进程、线程、协程这些概念似懂非懂的,要不咱们今天就好好聊聊这些?

蛋先生:当然可以

丹尼尔:先说说进程吧,从字面意思上看,是不是可以理解为正在运(进)行的程序?

蛋先生:正是如此,程序是静态的,而进程则是动态的

丹尼尔:说得我更糊涂了

蛋先生:好吧,以你电脑上的视频播放器(就是一个程序)为例。当你不双击它时,它就是一个安静的美男子——哦不,就是一份静静躺在硬盘上的代码

丹尼尔:别逗我了,蛋兄

蛋先生:( ╯▽╰) 但当你双击它时,它就通过进程“动”起来了

丹尼尔:进程做了什么让它“动”起来了?

蛋先生:程序是代码,比如播放逻辑的代码。要让视频播放,这些代码必须执行起来对吧

丹尼尔:确实。那进程是怎么执行这些代码的?

蛋先生:进程会利用操作系统的调度器分配给它的 CPU 时间片,通过 CPU 来执行代码(注意:现代操作系统都是直接调度线程,不会调度进程哦)

丹尼尔:原来如此,操作系统给进程分配了 CPU 时间片资源。那还有其他的资源吗?

蛋先生:代码执行过程,需要存储一些数据,所以进程还分配有内存空间资源

丹尼尔:都存些什么数据呢?

蛋先生:程序代码本身就需要先存储起来。然后代码执行过程中的变量,参数什么的,也是需要存储的。给个图你了解一下吧


丹尼尔:哦,还有其它资源吗?

蛋先生:程序可能会执行一些 I/O 任务,比如视频播放器需要加载视频,这些视频数据可能从本地文件加载,也可能从网络上加载,这就需要文件描述符资源。计算,存储,I/O 涉及的三大资源,就是分配给进程最主要的资源了。而进程就是分配资源的基本单位了

丹尼尔:原来如此,代码执行,数据存储,I/O 操作,程序就能运行起来了

蛋先生:正是这样。有了进程,我们可以同时运行多个程序。比如,你可以一边播放视频,一边编辑文档,每个程序都有自己的进程,互不干扰。即使它们都是同一份代码,但各自播放的内容和进度都可以不同

丹尼尔:明白了

蛋先生:既然你有编程基础,我就简单总结一下吧。

什么是进程?进程就是程序的实例(就像面向对象编程中的类,类是静态的,只有实例化后才运行,且同一个类可以有多个实例)

为什么需要进程?为了让程序运行起来(如果程序不运行,用户昨看视频捏)

线程

丹尼尔:这个总结我喜欢,接下来该聊聊线程了

蛋先生:进程(可以看成只有一个线程的进程)同时只能做一件事,所以你的视频播放器的工作方式就像以下


丹尼尔:那样的体验肯定糟糕透了,视频完全加载并解码完之前,啥都看不了

蛋先生:没错,所以我们期望能够一边加载和解码,一边播放,这样就不会浪费时间空等了。为了实现这个目的,一个进程就需要进化成多个线程来同时执行多个任务


丹尼尔:那如果一个进程只能做一件事,我用两个进程不也可以同时做两件事吗?


蛋先生:你说得对,但进程间是完全独立的,互不干扰。而线程则共享同一个进程的资源,所以线程间交换数据更方便,几乎没有通讯损耗。但进程间交换数据就麻烦多了,得通过一些通讯机制,比如管道、消息队列之类的

想象一下,我和你住在不同的房子,你要寄给我一箱牛奶,就得通过快递等方式寄给我。但如果我和你住在同一个房子,你买了牛奶只要往冰箱一放,我只要去冰箱一拿,多方便啊


丹尼尔:那线程都共享进程的什么资源呢?

蛋先生:分配给进程的资源,绝大部分都是线程间共享的。比如内存空间的代码段,数据段,堆,比如文件描述符等。而栈则是每个线程特有的,因为线程是程序执行的最小单位,它需要记录自己的局部变量等

共享资源覆盖

丹尼尔:线程之间共享资源,总感觉会有什么问题

蛋先生:大部分情况下线程之间还是可以和平共处的,但有一种情况,就是大家都想对同个资源进行写操作时,就会发生覆盖,导致数据不一致等问题

丹尼尔:能具体说一说吗?

蛋先生:为了更容易理解,我们借助以下代码来说明。如果两个线程来运行 main 方法,会有概率出现一些让你费解的结果

public class Main {
     // 定义一个静态成员变量 a 
    private static int a = 1;

     // 定义一个方法 add 来增加 a 的值 
    public static void add() {
        a += 1;
    }

    public static void main(String[] args) {
        add();
        System.out.println("a 的值是: " + a);  // 输出 a 的值 
    }
}

丹尼尔:怎么说?

蛋先生:a 是个静态成员变量,它存储在进程内存空间的数据段,共享于多个线程,所以它属于线程间共享的资源对吧

丹尼尔:没错

蛋先生:我们再看下add方法的逻辑a += 1, 这么简单的代码,在底层并非原子操作,而是分为三个步骤

步骤一:获取 a 变量的值

步骤二:执行 +1 运算

步骤三:将运行结果赋值给 a

丹尼尔:那会有什么问题呢?

蛋先生:如果线程 1 在执行完步骤一和步骤二,还没执行步骤三时,操作系统进行了 CPU 调度,发生了线程切换,使得线程 2 也开始执行步骤一和步骤二。接下来线程 1 和线程 2 都会各自执行步骤三。因为 add 方法执行了两次,正确的结果 a 的值应该是 +2。但很遗憾,结果是 +1。这样的结果有时候会让你摸不着头脑,而不稳定的结果也将会导致应用的不稳定

丹尼尔:啊,是这样啊。那该怎么办?

蛋先生:解决方法有很多种,比如加锁方案,比如无锁方案等,需要根据实际情况选择。这个话题比较复杂,我们后面再找时间详细探讨吧。现在只要知道多线程会有资源覆盖的问题就行了

上下文切换

丹尼尔:好的,明白了。刚才提到线程切换,线程切换到底发生了什么呢?

蛋先生:线程切换会进行线程上下文切换。线程在运行时,实际上是在执行代码,而执行代码过程中需要存储一些中间数据,也可能会执行一些 I/O 操作。如果过程中被中断,是不是得保留现场,以便下次恢复继续运行?

丹尼尔:嗯,确实需要,但具体都存储些什么呢?

蛋先生:首先是下一个要执行的代码,这个存储在程序计数器中。然后是一些中间数据如局部变量等,会存储在线程栈中。为了加速计算,中间数据中对当前指令执行至关重要的部分会存储在寄存器中。所以,程序计数器需要保存,寄存器需要保存,线程栈指针也需要保存

丹尼尔:“中间数据中对当前指令执行至关重要的部分会存储在寄存器”,能举个例子吗?

蛋先生:假设以下代码,当在执行 add 方法时,x, y, a, b 会压进线程栈中。而其中 a, b 是和当前运算最相关的,则会存储在寄存器中,以加速 CPU 的运算

int add(int a, int b) {
    return a + b;
}

int main() {
    int x = 10;
    int y = 20;
    int result = add(x, y);
    return 0
}
协程

丹尼尔:哦,原来如此。线程已经相当不错了,那协程又是怎么回事呢?

蛋先生:回想一下,我们之前一个线程负责运行加载和解码逻辑,另一个线程负责播放逻辑,对吧?

丹尼尔:没错,有什么问题吗?

蛋先生:其实还有优化的空间。线程在执行加载视频片段时,必须等待结果返回才能执行解码操作


丹尼尔:确实,加载片段的等待时间似乎又被浪费了

蛋先生:没错,我们可以充分利用这段时间。只需让线程在加载的同时进行解码,就能大幅减少加载等待的时间。而这正是协程所能发挥的作用


丹尼尔:哇,蛋兄,你可真是个会过日子的人,这么精打细算。但我只要用不同的线程分别处理加载和解码,不也能达到同样的效果吗?

蛋先生:可以是可以,但多线程会带来一些问题

丹尼尔:啥问题呢?

蛋先生:首先,一个线程用于执行加载操作,这主要是 I/O 操作,几乎不消耗 CPU 资源,导致该线程长时间处于阻塞状态,这是很浪费的。当然,你可以让它休眠以释放 CPU 时间,但创建线程本身就有开销,线程切换同样有开销。相比之下,协程非常轻量,创建和切换的开销极小

丹尼尔:为什么协程的创建和切换的开销极小呢?

蛋先生:主要是因为它并非操作系统层面的东西,就不涉及内核调度。一般是由编程语言来实现(比如 Python 的 asyncio 标准库),它属于用户态的东西

丹尼尔:那协程不会有像多线程那样的资源覆盖问题吗?

蛋先生:线程的执行时机由操作系统调度,程序员无法控制,这正是多线程容易出现资源覆盖的主要原因。而协程的执行时机由程序自身控制,不受操作系统调度影响,因此可以完全避免这类问题

此外,同一个线程内的多个协程共享同一个线程的 CPU 时间片资源,它们在 CPU 上的执行是有先后顺序的,不能并行执行。而线程是可以并行执行的

丹尼尔:那协程是如何实现这一点的呢?

蛋先生:协程(coroutine),其实是一种特殊的子程序(subroutine,比如普通函数)。普通函数一旦执行就会从头到尾运行,然后返回结果,中间不会暂停。而协程则可以在执行到一半时暂停。利用这一特性,我们可以在遇到 I/O 这类不消耗 CPU 资源的操作时,将其挂起,继续执行其他计算任务,充分利用 CPU 资源。等 I/O 操作结果返回时,再恢复执行

丹尼尔:感觉很像 NodeJS 的异步 I/O 啊

蛋先生:没错,它们的目的都是在一个线程内并发执行多个任务。不过在叫法和实现上会有一些差异

丹尼尔:感觉今天了解得够多了,谢谢蛋兄

蛋先生:后会有期!


特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
上海网红被告上法庭!自称复旦交大双硕士,宝妈们愤怒:收完钱就被拉黑

上海网红被告上法庭!自称复旦交大双硕士,宝妈们愤怒:收完钱就被拉黑

上观新闻
2024-11-14 14:42:40
巴西爆冷1-1,维尼修斯失点+妙传被浪费,拉菲尼亚世界波难换3分

巴西爆冷1-1,维尼修斯失点+妙传被浪费,拉菲尼亚世界波难换3分

侧身凌空斩
2024-11-15 06:56:49
成本1亿上映1天就被判死刑,观众齐刷退票,这电影就是个笑话

成本1亿上映1天就被判死刑,观众齐刷退票,这电影就是个笑话

得得电影
2024-11-14 16:30:03
性生活里的那些“高光”时刻

性生活里的那些“高光”时刻

智见派
2024-11-11 13:13:54
倒闭15000家,曾经风靡各大商场的酸菜鱼,为啥无人问津了?

倒闭15000家,曾经风靡各大商场的酸菜鱼,为啥无人问津了?

我不是博士
2024-11-14 09:05:10
中国的国鸟是啥?99%的中国人都不知道,看完终于明白了...

中国的国鸟是啥?99%的中国人都不知道,看完终于明白了...

中国艺术家
2024-11-15 05:13:19
特朗普团队据悉计划取消电动汽车税收抵免政策

特朗普团队据悉计划取消电动汽车税收抵免政策

界面新闻
2024-11-15 07:20:06
吕志和去世,全红婵未在社交媒体上哀悼,遭网暴被谴责情商太低

吕志和去世,全红婵未在社交媒体上哀悼,遭网暴被谴责情商太低

娱贝勒
2024-11-14 07:52:27
解放军台海巡航升级,马英九露真面目,称大陆若武统,台岛不接受

解放军台海巡航升级,马英九露真面目,称大陆若武统,台岛不接受

现代小青青慕慕
2024-11-15 07:39:25
中方从未有过的强硬!二度反击后,一个强硬信号直接扣在欧盟头上

中方从未有过的强硬!二度反击后,一个强硬信号直接扣在欧盟头上

赵探长TALK
2024-11-15 08:53:56
萝莉岛:小李子600万美元卖身希拉里,好莱坞“美男子”就此沦陷

萝莉岛:小李子600万美元卖身希拉里,好莱坞“美男子”就此沦陷

南城无双
2024-11-11 00:20:21
1979年,党中央抓捕许世友儿子,许世友得知后:抓得好,抓得妙

1979年,党中央抓捕许世友儿子,许世友得知后:抓得好,抓得妙

大海的诺言
2024-10-04 08:55:11
笑不活了,广东是得罪了冬天吗?还是全国瞒着广东过冬?评论炸锅

笑不活了,广东是得罪了冬天吗?还是全国瞒着广东过冬?评论炸锅

笑熬浆糊111
2024-11-15 00:05:22
真没想到,台湾亲民党主席宋楚瑜在接受采访时,竟然语出惊人!

真没想到,台湾亲民党主席宋楚瑜在接受采访时,竟然语出惊人!

现代小青青慕慕
2024-11-13 06:33:18
范冰冰饭局照流出,喝酒还吐舌头,素颜温婉大方,和妆后判若两人

范冰冰饭局照流出,喝酒还吐舌头,素颜温婉大方,和妆后判若两人

南城无双
2024-10-25 23:54:18
证监会开始“降温”股市!11月15日,A股将会继续下跌?

证监会开始“降温”股市!11月15日,A股将会继续下跌?

风口招财猪
2024-11-15 02:09:30
强烈建议,暂停王楚钦的所有比赛,他不应该再参加比赛了!

强烈建议,暂停王楚钦的所有比赛,他不应该再参加比赛了!

秋眼体育
2024-11-14 10:06:05
曝美国64%原住民投票给特朗普,网友:原住民深知非法移民的危害

曝美国64%原住民投票给特朗普,网友:原住民深知非法移民的危害

不掉线电波
2024-11-14 16:44:28
陈百祥的言论再次冲上了全国热搜,广东网友:难免出现歧义和纷争

陈百祥的言论再次冲上了全国热搜,广东网友:难免出现歧义和纷争

校长侃财
2024-11-15 10:09:47
3种中药已被国家药典禁用?不仅有肾毒性还致癌,别再以为是好药

3种中药已被国家药典禁用?不仅有肾毒性还致癌,别再以为是好药

39健康网
2024-11-14 11:51:14
2024-11-15 13:48:51
腾讯技术工程
腾讯技术工程
不止于技术
1193文章数 600关注度
往期回顾 全部

科技要闻

奇瑞董事长夸余承东:你改名余成功吧

头条要闻

一天内两省迎来省政府党组新成员 一人曾任重庆副市长

头条要闻

一天内两省迎来省政府党组新成员 一人曾任重庆副市长

体育要闻

我们究竟需要一支怎样的国家队?

娱乐要闻

娜扎和张云龙恋爱,男帅女美挺好

财经要闻

紫金矿业哥国矿山到底"被掠走"多少黄金?

汽车要闻

售136.8万起 路特斯EMEYA繁花高定版亮相车展

态度原创

时尚
数码
亲子
家居
教育

为了省钱,懒人穿衣都开始玩「叠叠乐」

数码要闻

极摩客EVO-X1迷你机上架:旗舰锐龙AI 9 HX 370杀到5299元

亲子要闻

让孩子从小接触科学,打通对科学的爱好

家居要闻

现代简约 彰显实用性

教育要闻

不是,别人家大学怎么在风景区啊!羡慕❤️

无障碍浏览 进入关怀版