use*_*714 125
协程和并发在很大程度上是正交的.协同程序是一种通用控制结构,其中流控制在两个不同的例程之间协同传递而不返回.
Python中的'yield'语句就是一个很好的例子.它创造了一个协程.遇到'yield'时,保存函数的当前状态,并将控制权返回给调用函数.然后,调用函数可以将执行转移回让步功能,并且其状态将恢复到遇到"yield"并且将继续执行的程度.
Nan*_*iao 71
来自Lua的编程," Coroutines"部分:
协程类似于一个线程(在多线程意义上):它是一个执行线,有自己的堆栈,它自己的局部变量,以及它自己的指令指针; 但它与其他协同程序共享全局变量和其他任何东西.线程和协同程序之间的主要区别在于,从概念上(或在字面上,在多处理器机器中),具有线程的程序并行运行多个线程.另一方面,协同程序是协作的:在任何给定时间,具有协同程序的程序仅运行其协同程序之一,并且此运行协程仅在明确请求被挂起时才暂停其执行.
所以重点是:协同程序是"协作的".即使在多核系统中,在任何给定时间只有一个协程运行(但多个线程可以并行运行).协同程序之间存在非抢占式,运行协程必须明确放弃执行.
对于" concurrency",你可以参考Rob Pike的幻灯片:
并发性是独立执行计算的组合.
因此在协程A的执行期间,它将控制传递给协程B.然后经过一段时间后,协程B将控制权传递给协程A.由于协程之间存在依赖关系,并且它们必须串联运行,因此这两个协程不是并发的.
mr1*_*011 30
我发现大多数答案太技术性,即使这是一个技术问题.我很难尝试理解协同程序.我有点得到它,但后来我没有得到它.
我发现这里的答案非常有帮助:
https://dev.to/thibmaek/explain-coroutines-like-im-five-2d9
引用Idan Arye的话:
为了建立你的故事,我会这样说:
你开始看动画片,但这是介绍.你没有观看介绍,而是转到游戏并进入在线大厅 - 但它需要3名玩家,只有你和你的妹妹在其中.而不是等待其他玩家加入你切换到你的作业,并回答第一个问题.第二个问题包含指向您需要观看的YouTube视频的链接.你打开它 - 它开始加载.您可以切换回卡通片,而不是等待它加载.介绍结束了,所以你可以观看.现在有广告 - 但同时第三个玩家加入,所以你切换到游戏等等......
我们的想法是,您不仅要快速切换任务,以使其看起来像是在一次性完成任务.您利用等待事情发生的时间(IO)来做其他需要您直接关注的事情.
绝对检查链接,还有更多,我不能引用一切.
Twi*_*kle 11
Coroutine类似于子程序/线程.不同之处在于,一旦调用者调用了子例程/线程,它就永远不会返回给调用者函数.但是,协程可以在执行一些代码后返回给调用者,允许调用者执行一些自己的代码并返回到协程点,在那里它停止执行并从那里继续执行.即.一个协程有多个入口和出口点
Iza*_*ana 10
我发现这个链接的解释非常简单。除了本答案中的最后一个要点之外,这些答案都没有试图解释并发性与并行性。
引自传奇人物 Joe Armstrong 的“编程 Erlang”:
并发程序在并行计算机上可能运行得更快。
并发程序是用并发编程语言编写的程序。我们出于性能、可伸缩性或容错性的原因编写并发程序。
并发编程语言是一种具有用于编写并发程序的显式语言结构的语言。这些结构是编程语言的一个组成部分,在所有操作系统上的行为方式都相同。
并行计算机是具有多个可以同时运行的处理单元(CPU 或内核)的计算机。
所以并发并不等同于并行。您仍然可以在单核计算机上编写并发程序。分时调度器会让你感觉你的程序是并发运行的。
并发程序有可能在并行计算机中并行运行,但不能保证。操作系统可能只给你一个内核来运行你的程序。
因此,并发是来自并发程序的软件模型,并不意味着您的程序可以在物理上并行运行。
“coroutine”这个词由两个词组成:“co”(合作)和“routines”(函数)。
一种。它实现了并发还是并行?
简单来说,让我们在单核计算机上讨论它。
并发是通过操作系统的时间共享来实现的。线程在 CPU 内核上为其分配的时间范围内执行其代码。它可以被操作系统抢占。它也可能将控制权交给操作系统。
另一方面,协程将控制权交给线程内的另一个协程,而不是操作系统。因此,一个线程中的所有协程仍然利用该线程的时间范围,而不会将 CPU 核心让给由操作系统管理的其他线程。
因此,您可以认为协程由用户而不是操作系统(或准并行)实现分时。协程在分配给运行这些协程的线程的同一个内核上运行。
协程是否实现了并行性?如果是受 CPU 限制的代码,则不会。与分时共享一样,它让您感觉它们是并行运行的,但它们的执行是交错而不重叠的。如果它是 IO 绑定的,是的,它通过硬件(IO 设备)而不是您的代码实现并行。
湾 与函数调用的区别?
如图所示,不需要调用return切换控制。它可以在没有return. 协程保存并共享当前函数帧(堆栈)上的状态。因此它比函数轻得多,因为当call ret.
如果您仍然感到困惑,这里有一个非常简单的方法来理解co-routine. 首先,什么是routine?用外行人的话来说,例行公事是我们一次又一次做的事情(例如,你早上的例行公事)。相似地。在编程语言中,aroutine是我们一次又一次使用的一段代码,例如a function。现在,如果你看看 a 的一般特征function or routine(注意:我谨慎地交替使用这两个术语),只要函数需要输出结果,它就会需要一些输入并占用 CPU 线程。意思是,functions or routines正在阻止代码中的调用。然而, aco-routine是一种特殊的例程,它可以与其他例程同时共存(“co-routine”一词的“co”部分由此而来),我们可以在编程语言中借助异步编程。在异步编程中,当一个协程正在等待某件事发生(例如,磁盘IO)时,另一个协程将开始工作,并且当该协程处于等待状态时,另一个协程最终将被激活减少我们代码的等待时间。
如果您理解了上述内容,让我们看看如何在 Python 中创建协同例程函数。您可以定义一个协同例程函数,如下所示 -
async def my_coroutine_function():
return 123
Run Code Online (Sandbox Code Playgroud)
await你可以通过在协程前面添加-来调用上面的协程
my_result = await my_coroutine_function()
Run Code Online (Sandbox Code Playgroud)
总而言之,
当您正在观看电视节目时,广告一出现,您就拿起手机给朋友发短信 - 您刚刚所做的就是异步编程。当你的电视节目(协同例程)处于等待状态时,你继续并激活你的另一个协同例程(给你的朋友发短信)。
基本上,有两种类型的协同程序:
Kotlin实现无堆栈协程 - 这意味着协同程序没有自己的堆栈,因此它们不会映射到本机线程.
这些是启动协程的功能:
launch{}
async{}
Run Code Online (Sandbox Code Playgroud)
您可以从这里了解更多信息:
https://www.kotlindevelopment.com/deep-dive-coroutines/
https://blog.mindorks.com/what-are-coroutines-in-kotlin-bf4fecd476e9
协程是实现并发的单线程解决方案。
A-Start ------------------------------------------ A-End
| B-Start -----------------------------------------|--- B-End
| | C-Start ------------------- C-End | |
| | | | | |
V V V V V V
1 thread->|<-A-|<--B---|<-C-|-A-|-C-|--A--|-B-|--C-->|---A---->|--B-->|
Run Code Online (Sandbox Code Playgroud)
与多线程解决方案相比:
thread A->|<--A| |--A-->|
thread B------>|<--B| |--B-->|
thread C ---------->|<---C| |C--->|
Run Code Online (Sandbox Code Playgroud)