什么是协程?它们与并发性有什么关系?
当前回答
协程类似于子例程/线程。 区别在于,一旦调用方调用了子例程/线程,它将永远不会返回到调用方函数。 但是协程可以在执行几段代码后返回到调用方,允许调用方执行一些自己的代码,并返回到它停止执行的协程点,并从那里继续。 ie。协程有多个入口点和出口点
其他回答
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()
最后,
当你正在看电视节目,广告一出现,你就拿起手机给朋友发短信——你刚刚做的就是异步编程。当你的电视节目(一个合作程序)处于等待状态时,你继续前进,让你的另一个合作程序(给你的朋友发短信)处于激活状态。
另一方面, 在python中,gevent库是一个基于协程的网络库,它为您提供线程类功能,如异步网络请求,而无需创建和销毁线程的开销。所使用的协程库是绿色的。
在Lua编程中,“协程”部分:
A coroutine is similar to a thread (in the sense of multithreading): it is a line of execution, with its own stack, its own local variables, and its own instruction pointer; but it shares global variables and mostly anything else with other coroutines. The main difference between threads and coroutines is that, conceptually (or literally, in a multiprocessor machine), a program with threads runs several threads in parallel. Coroutines, on the other hand, are collaborative: at any given time, a program with coroutines is running only one of its coroutines, and this running coroutine suspends its execution only when it explicitly requests to be suspended.
所以关键是:协程是“协作的”。即使在多核系统中,也只有一个协程在任何给定时间运行(但多个线程可以并行运行)。协程之间存在不可抢占性,运行中的协程必须显式放弃执行。
关于“并发性”,你可以参考Rob Pike的幻灯片:
并发是独立执行计算的组合。
所以在协程A的执行过程中,它把控制权传递给了协程B。经过一段时间后,协程B又把控制权传递给了协程A。由于协程之间存在依赖关系,它们必须串联运行,所以这两个协程不是并发的。
我发现大多数答案都太专业了,尽管这是一个技术问题。我很难理解协同程序的过程。我有点明白,但我不能同时明白。
我发现这个答案非常有用:
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.
一定要检查链接,还有更多我不能引用的东西。
我将详述@user21714的答案。协程是独立的执行路径,不能同时运行。它们依赖于一个控制器(例如python控制器库)来处理这些路径之间的切换。但是为了实现这一点,协同程序本身需要调用yield或类似的结构,以允许它们的执行暂停。
相反,线程运行在独立的计算资源上,并且彼此并行。由于它们位于不同的资源上,因此不需要调用yield来允许其他执行路径继续进行。
您可以通过启动一个多线程程序(例如jvm应用程序)来看到这种效果,其中所有八个核心i7超线程核心都被利用了:您可能会在Activity Monitor或Top中看到797%的利用率。相反,当运行一个典型的python程序(即使是带有协程或python线程的程序)时,利用率最高将达到100%。例如,一台机器超线程。