协程与线程的区别_跟涛哥一起学嵌入式 27:一个小故事,让你明白进程、线程和协程的区别...

进程、线程和协程,是多任务编程中的常用术语。很多初学者分不清它们之间的区别,今天就以一个小故事为引子,让大家搞清楚他们之间的本质区别。

话说在西凉女儿国,大唐文化传播有限公司CEO唐僧招聘了三个员工做游戏直播,他们分别是:孙悟空、猪八戒和沙僧。唐僧分别给他们租了三套一室一厅的房子,独门独户,他们三个每人各住一套,独享各自的卫生间和厨房,互不干扰。这有点类似于进程,在Linux环境下,每个进程有自己各自独立的 4G 地址空间,大家互不干扰对方,如果两个进程之间通信的话,还需要借助第三方进程间通信工具 IPC 才能完成。

e8dac0a1e52b75d6efc66c777a62c8e2.png

如上所示,进程A和进程B,各自有4G地址空间,除了1G的内核空间是共享的,用户空间则是相互独立的。不同的进程通过页表映射,映射到物理内存上各自独立的存储空间,在操作系统的调度下,分别轮流占用CPU去运行,互不干扰、互不影响,甚至相互都不知道对方。在每个进程的眼里,CPU就是他的整个世界,虽然不停地被睡眠,但是一旦恢复运行,一觉醒来,仿佛什么都没发生过一样,认为自己拥有整个CPU,一直在占有它。这就像悟空、八戒和沙僧一样,各自在自己的房间里,互相不知道对方。

5ca2f2a3f78692672c63b11224508a68.png

后来公司不景气,为了节省开支,原来的三套房子都退了,唐僧给他们三个租了一套三室一厅的房子,三个人合租。大家可能都跟别人合租过,每个人都有自己的卧室,这是私人空间,其它的像厨房、客厅、卫生间则是公用的。当大家都要使用厨房或卫生间的时候,冲突可能就产生了:比如早上,大家都要使用卫生间,到了晚上大家可能都要使用厨房做饭。到底谁先用?用多久?这是个大难题,比如八戒,喜欢在厨房里做好吃的,一做就是3小时,红烧猪蹄、红烧鸡爪......。害得其他人无法做饭,为此和沙僧冲突不断;比如悟空,喜欢早上去卫生间蹲坑,一蹲就是俩小时,害得别人早上无法洗涮,上班迟到,为此跟八戒也是打了好几架,冲突不断。

这一点跟线程很类似,在一个进程中,可能存在多个线程,每个线程类似于合租的每个租客,除了自己的私有空间外,还跟其它线程共享进程的很多资源,如地址空间、全局数据、代码段、打开的文件等等。

f4c2229179648dc21db6a3521f262ce8.png

当多个线程访问一些全局变量或共享资源时,可能也会产生竞争和冲突,就像八戒和沙僧抢厨房一样,八戒的猪蹄在锅里正炖着呢,沙僧进来二话没说,就把猪蹄倒在了一边,抢了锅开始烧水煮面条。那该怎么办呢?办法总是有的:唐僧从观音姐姐那里借了一把锁,每天早上和晚上都来到他们三个那里,谁想用厨房,要先申请锁,拿到锁后,你进去,把门锁上就可以了,别人再急也没用,等你用好了,解锁开门,把锁还给唐僧,其他人拿到锁,锁上门,然后才能开始使用厨房。通过这种加锁解锁的方式,访问一些共享资源的冲突和竞争解决了,从此三兄弟和睦相处,再也没打过架。在线程中,通过各种加锁解锁的同步机制,一样可以用来防止多个线程访问共享资源产生冲突,比如互斥锁、条件变量、读写锁等。冲突是解决了,但是开销却变大了,上个厕所,还得申请锁,锁上门才能用,使用完再开门,释放锁,太麻烦了。在线程中也是一样,不断地加锁解锁,CPU状态做各种转换,开销很大,那怎么办?协程此刻就应运而生了。

三兄弟也觉得这样太麻烦了,唐僧每天过来协调,也很累。后来他们三个经过商量后,决定和谐相处:不再争抢厨房和卫生间,大家协商着来。悟空蹲坑蹲到一半,便意消了一大半,便主动喊八戒:二师弟,我先出去,你进来吧。八戒很感动,晚上在厨房炖好了猪蹄后,主动喊沙僧:三师弟,我做好了一份菜了,我先吃着,红烧鸡爪我待会再做,你先进来煮面吧!看看,多么和谐的三兄弟~

协程和线程一样,多个协程也共享很多资源:地址空间、代码段、全局数据等。为了提高程序运行效率,防止程序阻塞,以及减少不断加锁解锁带来的开销,根据需要,协程自己会主动让出CPU,让给其它程序执行,而不是像原先的悟空那样,卫生间上了锁,在里面一蹲就是俩小时,占了茅坑就是不出来,让其他人在外面干等。

f87ce67b6b4db695b0bd489140752989.png

协程一般常用在网站后台、手机APP后台等访问量巨大的服务器场景中,成千上万的访问量,如果使用线程,开销很大,使用协程可以更好地应对这一场景。但是协程也有缺点,它往往是围绕一个CPU做文章,无法利用多核。现在很多CPU都是多核多线程了,因此在实际的场景应用中,往往是多进程+协程的形式来弥补这一缺陷,即利用了多核,也减少了多线程带来的各种开销,效率大大提高。

以上通过三兄弟合租的故事,让大家对进程、线程和协程有了一个感性的认识。想要深入理解,还需要进一步的学习和编程实践。《Linux系统编程》第07期:多线程编程入门视频教程,和练手项目:使用C语言实现协程编程实战教程已经更新完毕发布了,可通过淘宝平台:https://wanglitao.taobao.com 购买。已经购买课程的学员可以直接下载观看了,视频课程也会稍后发布到51CTO等各大在线教育平台,大家可根据需要自行购买学习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值