搜索

用户登录

没有账号? 立即注册

QQ登录

只需一步,快速开始

点击进入授权页面

只需一步,快速开始

每早10点,为您奉上有深度的生物媒体资讯,更多消息,请关注我们其他社会化平台:

查看: 214|回复: 0
打印 上一主题 下一主题

协程的好处是什么?

[复制链接]
跳转到指定楼层
楼主
发表于 2014-9-27 21:29:52 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制。大致上有这么两种多任务技术,一种是抢占式多任务(preemptive multitasking),它让操作系统来决定何时执行哪个任务。另外一种就是协作式多任务(cooperative multitasking),它把决定权交给任务,让它们在自己认为合适的时候自愿放弃执行。

这两种多任务方式各有优缺点,前者固有的同步问题使得程序经常有不可预知的行为,而后者则要求任务具备相当的自律精神。 协程(coroutine)技术是一种程序控制机制,早在上世纪60年代就已提出,用它可以很方便地实现协作式多任务。在主流的程序语言(如C++、Java、Pascal等)里我们很少能看到协程的身影,但是现在不少动态脚本语言(Python、Perl)却都提供了协程或与之相似的机制,其中最突出的便是Lua。

协程,又称微线程和纤程等,据说源于 Simula 和 Modula-2 语言(我没有深究,有错请指正),现代编程语言基本上都有支持,比如 Lua、ruby 和最新的 Google Go,当然也还有最近很让我惊艳的 falcon。协程是用户空间线程,操作系统对其存在一无所知,所以需要用户自己去做调度,用来执行协作式多任务非常合适。其实用协程来做的东西,用线程或进程通常也是一样可以做的,但往往多了许多加锁和通信的操作。

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

一开始大家想要同一时间执行那么三五个程序,大家能一块跑一跑。特别是UI什么的,别一上计算量比较大的玩意就跟死机一样。于是就有了并发,从程序员的角度可以看成是多个独立的逻辑流。内部可以是多cpu并行,也可以是单cpu时间分片,能快速的切换逻辑流,看起来像是大家一块跑的就行。

但是一块跑就有问题了。我计算到一半,刚把多次方程解到最后一步,你突然插进来,我的中间状态咋办,我用来储存的内存被你覆盖了咋办?所以跑在一个cpu里面的并发都需要处理上下文切换的问题。进程就是这样抽象出来个一个概念,搭配虚拟内存、进程表之类的东西,用来管理独立的程序运行、切换。

后来一电脑上有了好几个cpu,好咧,大家都别闲着,一人跑一进程。就是所谓的并行。

因为程序的使用涉及大量的计算机资源配置,把这活随意的交给用户程序,非常容易让整个系统分分钟被搞跪。所以核心的操作需要陷入内核(kernel),切换到操作系统,让老大帮你来做。

有的时候碰着I/O访问,阻塞了后面所有的计算。空着也是空着,老大就直接把CPU切换到其他进程,让人家先用着。当然除了I\O阻塞,还有时钟阻塞等等。一开始大家都这样弄,后来发现不成,太慢了。为啥呀,一切换进程得反复进入内核,置换掉一大堆状态。进程数一高,大部分系统资源就被进程切换给吃掉了。后来搞出线程的概念,大致意思就是,这个地方阻塞了,但我还有其他地方的逻辑流可以计算,这些逻辑流是共享一个地址空间的,不用特别麻烦的切换页表、刷新TLB,只要把寄存器刷新一遍就行,能比切换进程开销少点。

行,故事讲到这里,我们来看看并发的好处:

  • 该干嘛干嘛,多逻辑流先天符合人类描述问题的习惯;
  • 对于I/O密集的应用,被I/O阻塞的时候能切换到计算中去,可以显著的提升程序的响应速度。


我们看到阻塞、切换到其他进程(线程)的操作,都会交由操作系统来完成。所以不管是进程还是线程,每次阻塞、切换都需要陷入系统调用(system call),先让CPU跑操作系统的调度程序,然后再由调度程序决定该跑哪一个进程(线程)。

如果我们不要这些功能了,我自己在进程里面写一个逻辑流调度的东西,碰着i\o我就用非阻塞式的。那么我们即可以利用到并发优势,又可以避免反复系统调用,还有进程切换造成的开销,分分钟给你上几千个逻辑流不费力。这就是协程。

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

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册  

本版积分规则

快速回复 返回顶部 返回列表