说说协程coroutine

作者: NickYang 分类: 心情随笔 发布时间: 2017-05-07 14:06

近几年来,协程的概念和使用被越多越多的人提到了,确实帮助很多人解决了很多问题,例如网络上的问题,异步逻辑流程控制等。我的工作中也接触到一些,所以打算总结下。

简单来说,协程就是一种用户态、编程语言层面的轻量级线程。

然而线程与协程又有很多差异的地方,线程是靠操作系统OS本身来调度,是抢占式的任务处理方式,谁抢到算谁的,所以大部分多线程程序中都要单独调用sleep来让出CPU给其他线程;线程每次阻塞、切换时都需要系统调用system call,然后调用调度函数来决定运行哪一个线程;协程拥有自己的用户态的上下文和栈(分为stackless和stackfulness,这个下一篇文章来讲),协程切换时,先将寄存器上下文和栈内容保存起来,再次切换回来的时候再恢复之前保存的内容继续运行;

通过上面的讲解,明白了一个道理,协程是编译器来保证的,线程是操作系统来调度的;协程能更好的保证流程,而线程需要仔细处理公共数据资源;协程本质是单线程的,能提高单个CPU core的性能,适合计算密集型的应用;协程切换非常轻量,所以能大量的使用,线程切换成本较高,一般要控制线程数。

 

协程的概念和原理明白了后,其实有点类似于异步事件驱动,可以看看libevent/libuv等经典的C语言库,发现大量使用了异步事件回调,有一个event_loop来循环检查要处理的事件,不过就是代码相对协程恶心了一些,协程能让用户以类似同步的方式来处理异步流程,更加便于理解。

 

不过协程也是有缺点的,无法利用现代多核机器的性能,所以还需要配合多进程来提高性能;有阻塞操作的时候依然会阻塞整个进程,需要用其他方式来解决。

还有一个东西是actor,这个是更符合人类思维的方式,属于类似消息通知的方式来处理异步事件,可惜现在没有非常好用的actor cpp库,其他语言有类似的库,例如Java的akka, .net的Akka.net, Orleans/Service fabric等。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

一条评论
  • vfhky

    2017 年 6 月 22 日 09:41

    go python这些弄进来的概念,apue上只有进程和线程的概念。

    潜水 Chrome浏览器 Windows 10 x64 Edition

发表评论

电子邮件地址不会被公开。 必填项已用*标注