什么是协程?它们与并发性有什么关系?
当前回答
另一方面, 在python中,gevent库是一个基于协程的网络库,它为您提供线程类功能,如异步网络请求,而无需创建和销毁线程的开销。所使用的协程库是绿色的。
其他回答
我发现大多数答案都太专业了,尽管这是一个技术问题。我很难理解协同程序的过程。我有点明白,但我不能同时明白。
我发现这个答案非常有用:
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.
一定要检查链接,还有更多我不能引用的东西。
协程类似于子例程/线程。 区别在于,一旦调用方调用了子例程/线程,它将永远不会返回到调用方函数。 但是协程可以在执行几段代码后返回到调用方,允许调用方执行一些自己的代码,并返回到它停止执行的协程点,并从那里继续。 ie。协程有多个入口点和出口点
协程是Kotlin语言中可用的很棒的特性 协程是一种新的异步、非阻塞的编写方式 代码(以及更多) 协程是轻量级线程。一根轻的线就意味着它 不映射到本机线程,因此不需要上下文切换 在处理器上,所以它们更快。 它不映射到本机线程上 协程和线程都是多任务处理。但是区别在于 线程由操作系统管理,协程由用户管理。
基本上,有两种类型的协程:
Stackless Stackful
Kotlin实现了无堆栈协程-这意味着 协程没有自己的堆栈,所以它们不会映射到本机线程上。
这些是启动协程的函数:
launch{}
async{}
你可以在这里了解更多:
https://www.kotlindevelopment.com/deep-dive-coroutines/
https://blog.mindorks.com/what-are-coroutines-in-kotlin-bf4fecd476e9
另一方面, 在python中,gevent库是一个基于协程的网络库,它为您提供线程类功能,如异步网络请求,而无需创建和销毁线程的开销。所使用的协程库是绿色的。
Kotlin 协程
[同步与异步]
[并发vs并行]
通常我们认为协程是轻量级线程,它们允许我们以同步的方式编写异步的、非阻塞的代码
至于Kotlin协程:
协程是一个合成糖/附加层,它允许你以非阻塞的方式运行任务,没有回调。协程由以下组件组成:
延续 作业-管理程序和保存它的状态 CoroutineScope(包含作业和Xontext)——处理作业组(层次结构)并管理它们(启动和取消) Dispatcher -用于处理线程池- Main, IO, Default… 上下文-像Map这样的数据结构,以保存一些日期,如Job, Dispatcher和自定义数据
让我们回顾一些例子
class MyClass {
val network = Network()
val fileSystem = FileSystem()
suspend fun downloadFile(): File {
//suspendCoroutine is key point
return suspendCoroutine { continuation ->
network.download(callback: Network.Callback {
override fun onSuccess(file: File) {
continuation.resume(file)
}
})
}
}
suspend fun saveFile(file: File) {
//suspendCoroutine is key point
return suspendCoroutine { continuation ->
fileSystem.save(callback: FileSystem.Callback {
override fun onSuccess() {
continuation.resume()
}
})
}
}
GlobalScope.launch {
val downloadResult = downloadFile() //1. suspend function
show(downloadResult) //2. UI
saveFile(downloadResult) //3. suspend function
}
延续
它创建了Continuation类,它是一个状态机,内部有invokeSuspend()函数。在任何挂起函数的末尾调用invokeSuspend()(像回调一样)
class Continuation {
int label;
//block of local variabels
File file;
void invokeSuspend(Object result) {
switch (label) {
case 0: {
label = 1;
downloadFile(this); //1. suspend function
return;
}
case 1: {
file = (File) result; //work with result
show(file); //2. UI
saveFile(file, this); //3.suspend function
return;
}
}
}
}
class MyClass {
fun downloadFile(continuation: Continuation): File {
//logic
continuation.invokeSuspend(file)
}
fun saveFile(file: File, continuation: Continuation) {
//logic
continuation.invokeSuspend()
}
}
暂停
suspended只是一个函数的标记,它将被添加新的延续参数(continue: continue) 分割状态机,这意味着它可以暂停机器 暂停函数应该在Continuation.resume() -> Continuation. invokesuspend()中调用Continuation.resume() 挂起的函数只能从couroutine调用
协程的行为完全依赖于库的实现