ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

为什么引入协程

2021-12-02 16:32:47  阅读:142  来源: 互联网

标签:为什么 协程 阻塞 用户 进程 线程 切换 引入


https://blog.csdn.net/qq_38836770/article/details/118329964

进程,线程,协程之间的关系是
进程可以有多个线程
线程可以有多个协程
资源消耗 进程 > 线程 > 协程

这个问题和既然有个进程为什么要引入线程的原因 很类似,
下面就类比的进行讲解

多线程之可以共享同一块地址和所有可用数据,这是进程所不具备的,
但带来的问题是多线程之间在进行数据同步的时候,就很有可能发生冲突(抢占式),所以往往需要添加锁来避免数据冲突(但加锁之后往往会影响程序的运行效率);
而协程因为存在于一个线程中,所以不存在写变量的冲突(非抢占式),所以执行的效率比线程高很多
线程要比进程更加轻量,创建一个线程要比创建一个进程快10 ~ 100倍,在切换的时候,由于进程是系统的多任务,进程的切换会带来大量的内存开销导致缺页中断,需要读取硬盘并加载到内存中;线程需要调用操作系统内核,涉及到从用户态切换到内核态,多个寄存器的刷新操作;而协程只有三个寄存器的值修改,只涉及到简单的现场保存和恢复
性能方面,性能其实是要根据实际的情况才能判断出优劣,脱离实际谈性能就是耍流氓,并不是东西越复杂性能越好,比如如果多个线程都是cpu密集型任务,那么并不能获得性能上的增强,但如果存在着大量的计算和大量的i/0处理,拥有多个线程能彼此重叠进行,从而加快程序的执行速度;协程也是类似的情况,可以把协程理解为在用户态下的线程,因为协程是非抢占式的,需要用户自己切换到其他协程,因此同一时间其实只有一个协程拥有运行权,协程的性能主要体现在IO,协程的本质其实就是可以被暂停以及可以被恢复的函数,若一个IO操作比较消耗时间,CPU可以换到另一个协程上运行,以免CPU时间在忙等中被白白浪费。
===============================================================================

作者:阿猫
链接:https://www.zhihu.com/question/20511233/answer/24260355
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

没有啥复杂的东西,考虑清楚需求,就可以很自然的衍生出这些解决方案。

    • 一开始大家想要同一时间执行那么三五个程序,大家能一块跑一跑。特别是UI什么的,别一上计算量比较大的玩意就跟死机一样。于是就有了并发,从程序员的角度可以看成是多个独立的逻辑流。内部可以是多cpu并行,也可以是单cpu时间分片,能快速的切换逻辑流,看起来像是大家一块跑的就行。
    • 但是一块跑就有问题了。我计算到一半,刚把多次方程解到最后一步,你突然插进来,我的中间状态咋办,我用来储存的内存被你覆盖了咋办?所以跑在一个cpu里面的并发都需要处理上下文切换的问题。进程就是这样抽象出来个一个概念,搭配虚拟内存、进程表之类的东西,用来管理独立的程序运行、切换。
    • 后来一电脑上有了好几个cpu,好咧,大家都别闲着,一人跑一进程。就是所谓的并行
    • 因为程序的使用涉及大量的计算机资源配置,把这活随意的交给用户程序,非常容易让整个系统分分钟被搞跪,资源分配也很难做到相对的公平。所以核心的操作需要陷入内核(kernel),切换到操作系统,让老大帮你来做。
    • 有的时候碰着I/O访问,阻塞了后面所有的计算。空着也是空着,老大就直接把CPU切换到其他进程,让人家先用着。当然除了I\O阻塞,还有时钟阻塞等等。一开始大家都这样弄,后来发现不成,太慢了。为啥呀,一切换进程得反复进入内核,置换掉一大堆状态。进程数一高,大部分系统资源就被进程切换给吃掉了。后来搞出线程的概念,大致意思就是,这个地方阻塞了,但我还有其他地方的逻辑流可以计算,这些逻辑流是共享一个地址空间的,不用特别麻烦的切换页表、刷新TLB,只要把寄存器刷新一遍就行,能比切换进程开销少点。
    • 如果连时钟阻塞、 线程切换这些功能我们都不需要了,自己在进程里面写一个逻辑流调度的东西。那么我们即可以利用到并发优势,又可以避免反复系统调用,还有进程切换造成的开销,分分钟给你上几千个逻辑流不费力。这就是用户态线程
  • 从上面可以看到,实现一个用户态线程有两个必须要处理的问题:一是碰着阻塞式I\O会导致整个进程被挂起;二是由于缺乏时钟阻塞,进程需要自己拥有调度线程的能力。如果一种实现使得每个线程需要自己通过调用某个方法,主动交出控制权。那么我们就称这种用户态线程是协作式的,即是协程

本质上协程就是用户空间下的线程。

========================================================================================

通俗易懂的回答:让原来要使用异步+回调方式写的非人类代码,可以用看似同步的方式写出来...

说协程性能好的,其实真正的原因是因为瓶颈在IO上面,而这个时候真正发挥不了线程的作用。

=======================================================================================

随口说
进程创建了一个个线程小弟用来给它服务,线程做小弟做久了,心想我也弄几个手下啊,然后它也背着操作系统偷偷整了几个小弟,给他干活,这几个小弟就是协程了。
介绍
协程,就是线程创建的执行体,同样线程需要维护每个协程的执行入口,栈基,栈指针和执行现场等,用来不同协程进行切换。由于用户态不能操作内核空间,所以协程只存在于用户空间中,操作系统是浑然不知的。
原因
既然切换也得保存现场、也得各种设置寄存器,那么它和本来的线程区别在哪?
首先,它是更加灵活、轻量级的,因为现在CPU、内存啥的确实厉害,线程这么大小的量级对于它们的计算速度来说,还是有点大的,所以就再小一点。
其次,现在高并发场合随处可见,各种移动设备每天产出大量数据,同时涌入如此多的数据,多开一些协程,压力就会小一些。毕竟线程切换还是需要用户态、内核态的转换,但是协程的话,只在用户空间中使用,所以不存在这个问题。
最后,让协程大放异彩的是其在I/O多路复用中的使用,具体细节另写一篇吧。
————————————————
版权声明:本文为CSDN博主「Pekue」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Pekue/article/details/117447312

====================================================================

作者:Ivony
链接:https://www.zhihu.com/question/50185085/answer/1342613525
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

其实从处理器的角度看协程更符合直觉,一个处理器核心本来就没法同时处理两件事情,要同时进行多件事情本来就需要正在运行的让出处理器,然后才能去处理另一件事情。只不过这个让出的过程是线程调度器主动抢占的。

所以线程调度器是假定不同的线程是毫无关系的,所以它平均的分配时间片让处理器雨露均沾。

但是很快人们发现这不是事情的全部,很多时候两个线程不是完全独立的,他们会操作同一个资源。这个时候人们又发明了同步锁,使得一段时间内只有一个线程可以操作这个资源,其他线程只能等待。

 

然后我们很快发现,这特么不是脱了裤子放屁么?处理器本来同一时间就只能有一个线程在运行。是线程调度器抢断划分时间片给其他线程跑,现在其他线程又说特么我要等前面那个线程用完了这个资源才能运行。

你特么早说啊,我抢什么抢?既然你们排他性的争抢同一个资源,你们一个个的跑不就好了,我就给你们排个队就完了。

 

也就是说,在所有线程相互独立且不会阻塞的模式下,抢断式的线程调度器是不错的选择。因为它可以保证所有的线程都可以被分到时间片不被程序员的垃圾代码所累。这对于某些事情来说是至关重要的,例如计时器、回调、IO触发器(譬如说处理请求)什么的。

但是在线程不是相互独立,经常因为争抢而阻塞的情况下,抢断式的线程调度器就显得脱了裤子放屁了,既然你们只能一个个的跑,那抢断还有什么意义?让你们自己去让出时间片就好了。

再往后,大家发现经常有阻塞的情况下,主动让出时间片的协程模式比抢占式分配的效率要好,也简单得多。

但是线程并不是一无是处,抢断式线程调度器事实上提供了准实时的体验。例如Timer,虽然不能确保在时间到达的时候一定能够分到时间片运行,但不会像协程一样万一没有人让出时间片就永远得不到运行……

比如说像JS这种语言,你要打开控制台敲个while(true);回车……

==================================================================

标签:为什么,协程,阻塞,用户,进程,线程,切换,引入
来源: https://www.cnblogs.com/axjlxy/p/15633863.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有