编译原理实战课
宫文学
北京原点代码 CEO
26066 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 55 讲
真实编译器解析篇 (19讲)
编译原理实战课
15
15
1.0x
00:00/00:00
登录|注册

34 | 并发中的编译技术(二):如何从语言层面支持协程?

协程的调度时机
channel机制
Stackful的特点
IO密集型的应用
生产者和消费者模式
Go语言的协程机制
Julia语言的协程机制
async/await关键字
generator功能
方法4:把线程封装成协程
方法3:基于JNI
方法2:做字节码操纵
方法1:给虚拟机打补丁
异步IO的协程模式
generator模式
libco协程库
C++20标准中的协程特性
Stackless Coroutine
Stackful Coroutine
调用协程时的控制流和栈桢管理
函数调用时的控制流和栈桢管理
适用场景
用户自己控制并发
占用资源少
文章探讨了在Java中实现协程的各种技术考虑
文章介绍了Goroutine使用栈的机制
一课一思
协程的实现机制
编译技术与语言特性的配合
对协程的深入认识
Julia和Go语言的协程实现
JavaScript中的协程
Java的协程实现
Python语言的协程实现
C++语言的协程实现
Stackful和Stackless的协程
调用栈和活动记录
协程的特点与使用场景
参考资料
课程小结
不同语言的协程实现和差异
协程的运行原理
协程(Coroutine)
并发中的编译技术(二):如何从语言层面支持协程?

该思维导图由 AI 生成,仅供参考

你好,我是宫文学。
上一讲我们提到了线程模式是当前计算机语言支持并发的主要方式。
不过,在有些情况下,线程模式并不能满足要求。当需要运行大量并发任务的时候,线程消耗的内存、线程上下文切换的开销都太大。这就限制了程序所能支持的并发任务的数量。
在这个背景下,一个很“古老”的技术重新焕发了青春,这就是协程(Coroutine)。它能以非常低的代价、友好的编程方式支持大量的并发任务。像 Go、Python、Kotlin、C# 等语言都提供了对协程的支持。
今天这一讲,我们就来探究一下如何在计算机语言中支持协程的奇妙功能,它与编译技术又是怎样衔接的。
首先,我们来认识一下协程。

协程(Coroutine)的特点与使用场景

我说协程“古老”,是因为这个概念是在 1958 年被马尔文 · 康威(Melvin Conway)提出来、在 20 世纪 60 年代又被高德纳(Donald Ervin Knuth)总结为两种子过程(Subroutine)的模式之一。一种是我们常见的函数调用的方式,而另一种就是协程。在当时,计算机的性能很低,完全没有现代的多核计算机。而采用协程就能够在这样低的配置上实现并发计算,可见它是多么的轻量级。
有的时候,协程又可能被称作绿色线程、纤程等,所采用的技术也各有不同。但总的来说,它们都有一些共同点
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

协程技术在编程语言中的支持和实现是本文的核心内容。文章首先介绍了协程的特点和使用场景,包括资源占用少、用户自控并发等特点,并通过生动的例子和图表说明了协程在生产者消费者模式和IO密集型应用中的应用场景。随后对比了同步编程和异步编程的优缺点,并指出了异步编程模型中的回调地狱问题。文章还深入探讨了协程的运行原理,包括协程的活动记录保存和恢复,以及实现协程的调度机制。接着介绍了Stackful和Stackless两种协程机制的特点和区别,以及对称和非对称协程的概念。最后,对C++、Python、Java、JavaScript、Julia和Go等常见语言中协程的支持和实现进行了梳理和比较。整篇文章通过生动的例子和图表,深入浅出地阐述了协程技术的特点、实现原理以及不同语言的支持情况,为读者提供了全面了解协程技术的基础知识。 C++20标准中增加的协程特性以及微软的Stackless模式的实现,以及腾讯的libco协程库的创新性共享栈机制,为读者展示了C++中协程的支持和应用。Python的generator模式和3.4版本之后引入的异步IO的协程模式,以及Python在高并发场景中的限制也得到了介绍。对于Java,文章提到了一些支持协程的方法,以及第三方库的实现情况。而JavaScript从ES6引入的generator功能和ES7引入的async/await支持异步编程,使得协程在JavaScript中的应用变得更加友好。这些内容为读者提供了对不同语言中协程支持和实现情况的全面了解。 在Goroutine实现了丰富的调度机制以后,它已经变得不完全由用户的程序来主导协程的调度了,而是能够更加智能、更加优化地实现协程的调度,由操作系统的线程调度器、Go语言的调度器和用户程序三者配合实现。这也是Go语言的一个重要优点。文章通过对不同语言中协程支持和实现情况的深入探讨,为读者提供了全面了解协程技术的基础知识,使其能够快速了解协程技术在编程语言中的应用和实现情况。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《编译原理实战课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(9)

  • 最新
  • 精选
  • 易昊
    这篇文章太有启发性了,我想照着文章给出的思路自己尝试实现一下协程

    作者回复: 牛!为你点赞!

    2020-09-19
    6
  • long
    协程为什么没有线程的使用,那么广泛和流行?

    作者回复: 我的理解:线程是操作系统层面就提供的,所以各门语言把线程封装一下,就可以提供给程序员使用。 而协程不是操作系统从底层就支持的,所以实现起来工作量要大一些。 另外,协程主要用于高并发的场景。如果你的程序对并发没有那个高的要求,那自然也就不需要使用协程了。

    2020-10-23
    4
  • myrfy
    老师提到了go的协程是做的最彻底的,但是这样的做法也使得他的ffi和cffi差别太大,cgo的调用效率低等问题。在提高go和c之间调用性能上,老师有什么思路吗?

    作者回复: 这个问题,其实要回到语言的设计上。每门语言都很难在所有的地方擅长。go语言调用c库的优先级,应该不是特别高,属于除非没有别的办法,就最好不去调用c。因为全部用go写的程序,才最适合它去做并发调度。 另外,作为go语言的设计目标,在abi转换上的这点开销,是无关紧要的。go语言做调度、做垃圾回收,都要有不少的开销。 不仅go调c不容易,c调go就更不容易了。因为像go这样的语言都带有gc。 作为对比,Rust的设计,使得它调c,以及c调rust都很方便,因为它们要满足的需求和底层的实现思路几乎是一样的。Rust不用程序员自己写malloc和free了,但只是编译器帮忙做了这件事情。

    2020-08-31
    2
  • kkxue
    深度和广度兼具,赞!

    作者回复: 感谢肯定:-)

    2020-10-03
  • Tino's Park
    请问老师:协程与异步 IO 结合是一个趋势;这个有进一步的介绍资料吗? 谢谢。

    作者回复: 1.首先,可以把Python的Async io和协程的关系学习一下。参考文章:https://realpython.com/async-io-python/ 据我私人渠道的消息,Python的异步io功能的作者,纠集了一拨人,做了一个初创公司,开发一种新的数据库,也是充分体现异步IO优势的那种。 2. JavaScript新引入的async/await关键字,也可以研究一下。跟Python类似。 3.腾讯开源的那个协程库,也是配合异步化的网络通讯的,你可以查阅他们的资料。 4.在erlang的世界里,io从来都是异步的。不过与之配合的并发模式是actor。你也可以查查相关的资料。 3.

    2020-09-22
  • sunbird
    技术牛的人很多,但能讲这么透彻的不多,以前好多想不通的问题,瞬间都想明白了,多谢。 对于协程用于高并发这一点还是有点不清楚。nio可以提高并发是因为其利用了设备中断和DMA的方式,从硬件优化了IO的效率。但协程还是靠线程来执行操作,它虽然占用的内存比较少,但个人感觉原理有点类似java中的线程池的概念,而线程池显然占用的内存更少,其和nio的结合对于并发来说岂不更好。 我感觉协程重点在于“协”这个字,和线程池比,他的不同协程之间的协作性好。不知道理解的对不对。 最近在学kotlin的协程,一直学不明白,看了这篇文章,才是真正懂了,再次感谢。
    2020-11-13
    1
  • enjoylearning
    读起来很有意思,对协程的理解又加深了一步
    2023-12-01归属地:北京
  • AKEI
    有个问题请教下老师。文章里面提到“在异步编程模型中,网络通讯等 IO 操作不必阻塞线程,而是通过回调来让主程序继续执行后续的逻辑。” 我的认知是,发起了io之后,操作系统必须要持有一个线程的fd,用于io返回后的回调的吧?这个持有的过程,异步模型就能让这个线程去继续做其他事吗?如果是这样,和io多路复用的区别在哪?
    2022-05-11
  • ifelse
    大开眼界
    2022-01-27
收起评论
显示
设置
留言
9
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部