什么是协程?它们与并发性有什么关系?


当前回答

协程类似于子例程/线程。 区别在于,一旦调用方调用了子例程/线程,它将永远不会返回到调用方函数。 但是协程可以在执行几段代码后返回到调用方,允许调用方执行一些自己的代码,并返回到它停止执行的协程点,并从那里继续。 ie。协程有多个入口点和出口点

其他回答

我将详述@user21714的答案。协程是独立的执行路径,不能同时运行。它们依赖于一个控制器(例如python控制器库)来处理这些路径之间的切换。但是为了实现这一点,协同程序本身需要调用yield或类似的结构,以允许它们的执行暂停。

相反,线程运行在独立的计算资源上,并且彼此并行。由于它们位于不同的资源上,因此不需要调用yield来允许其他执行路径继续进行。

您可以通过启动一个多线程程序(例如jvm应用程序)来看到这种效果,其中所有八个核心i7超线程核心都被利用了:您可能会在Activity Monitor或Top中看到797%的利用率。相反,当运行一个典型的python程序(即使是带有协程或python线程的程序)时,利用率最高将达到100%。例如,一台机器超线程。

来自Python Coroutine:

Python协程的执行可以在许多地方暂停和恢复 点(见协程)。在协程函数体内,等待 异步标识符成为保留关键字;等待表达式, Async for和Async with只能在协程函数中使用 的身体。

From Coroutines (c++ 20)

协程是一种可以挂起要恢复的执行的函数 以后。协程是无堆栈的:它们通过返回来暂停执行 给打电话的人。这允许执行顺序代码 异步(例如,不显式地处理非阻塞I/O 回调),并且还支持惰性计算无限上的算法 序列和其他用途。

与他人的答案比较:

在我看来,后面的恢复部分是一个核心的区别,就像@Twinkle一样。 虽然文件的很多方面还在完善中,但是这一部分和大部分的答案是相似的,除了@南晓

另一方面,协程是协作的:在任何给定的时间,一个 带有协程的程序只运行其中一个协程,并且 这个正在运行的协程仅在显式执行时才会暂停执行 请求被暂停。

因为引用自Program in Lua,可能是语言相关(目前不熟悉Lua),不是所有文档都只提到一个部分。

与concurrent的关系: 协程(c++ 20)中有一个“执行”部分。太长了,不能在这里引用。 除了细节,还有几个状态。

When a coroutine begins execution  
When a coroutine reaches a suspension point  
When a coroutine reaches the co_return statement  
If the coroutine ends with an uncaught exception  
When the coroutine state is destroyed either because it terminated via co_return or uncaught exception, or because it was destroyed via its handle 

正如@Adam Arold在@user217714的回答下的评论。并发性。 但它与多线程不同。 从std::线程

Threads allow multiple functions to execute concurrently. Threads begin execution immediately upon construction of the associated thread object (pending any OS scheduling delays), starting at the top-level function provided as a constructor argument. The return value of the top-level function is ignored and if it terminates by throwing an exception, std::terminate is called. The top-level function may communicate its return value or an exception to the caller via std::promise or by modifying shared variables (which may require synchronization, see std::mutex and std::atomic)

因为它是并发的,它就像多线程一样工作,特别是当等待是不可避免的(从操作系统的角度来看),这也是为什么它令人困惑的原因。

If you are still confused, here is a very simple way of understanding a co-routine. First off, what is a routine? In a lay man's term, a routine is something that we do again and again (for example, your morning routine). Similarly. in programming languages, a routine is a piece of code that we use again and again, e.g., a function. Now, if you look at the general characteristic of a function or routine (note: I am cautiously using these two terms interchangeably), it takes some inputs and hogs the CPU threads for as long as the function needs to output the result. Meaning, functions or routines are blocking calls in you code. However, a co-routine is a special kind of routine that can co-exist (the "co" part of the word co-routine comes from this) with other routines at the same time and we can make this happen in programming languages with the help of asynchronous programming. In Asynchronous programming, when one co-routine is waiting for something to happen (e.g., disk io), the other co-routine will start working and when this co-routine is in a waiting state the other co-routine will be active ultimately reducing the waiting time of our code.

如果你理解了上面的内容,让我们看看如何在Python中创建协程函数。可以像下面那样定义协程函数-

async def my_coroutine_function():
    return 123

你可以通过在协同程序-前面添加await来调用上面的协同程序

my_result = await my_coroutine_function()

最后,

当你正在看电视节目,广告一出现,你就拿起手机给朋友发短信——你刚刚做的就是异步编程。当你的电视节目(一个合作程序)处于等待状态时,你继续前进,让你的另一个合作程序(给你的朋友发短信)处于激活状态。

我发现大多数答案都太专业了,尽管这是一个技术问题。我很难理解协同程序的过程。我有点明白,但我不能同时明白。

我发现这个答案非常有用:

https://dev.to/thibmaek/explain-coroutines-like-im-five-2d9

引用伊丹·阿耶的话:

To build on your story, I'd put it something like this: You start watching the cartoon, but it's the intro. Instead of watching the intro you switch to the game and enter the online lobby - but it needs 3 players and only you and your sister are in it. Instead of waiting for another player to join you switch to your homework, and answer the first question. The second question has a link to a YouTube video you need to watch. You open it - and it starts loading. Instead of waiting for it to load, you switch back to the cartoon. The intro is over, so you can watch. Now there are commercials - but meanwhile a third player has joined so you switch to the game And so on... The idea is that you don't just switch the tasks really fast to make it look like you are doing everything at once. You utilize the time you are waiting for something to happen(IO) to do other things that do require your direct attention.

一定要检查链接,还有更多我不能引用的东西。

协程是Kotlin语言中可用的很棒的特性 协程是一种新的异步、非阻塞的编写方式 代码(以及更多) 协程是轻量级线程。一根轻的线就意味着它 不映射到本机线程,因此不需要上下文切换 在处理器上,所以它们更快。 它不映射到本机线程上 协程和线程都是多任务处理。但是区别在于 线程由操作系统管理,协程由用户管理。

基本上,有两种类型的协程:

Stackless Stackful

Kotlin实现了无堆栈协程-这意味着 协程没有自己的堆栈,所以它们不会映射到本机线程上。

这些是启动协程的函数:

launch{}

async{}

你可以在这里了解更多:

https://www.kotlindevelopment.com/deep-dive-coroutines/

https://blog.mindorks.com/what-are-coroutines-in-kotlin-bf4fecd476e9