想象一下,我们有一个迭代器,比方说iter(range(1, 1000)).我们有两种功能,每接受一个迭代器作为唯一的参数,说sum()和max().在SQL世界中,我们将其称为聚合函数.
有没有办法在不缓冲迭代器输出的情况下获得两者的结果?
要做到这一点,我们需要暂停和恢复聚合函数执行,以便为它们提供相同的值而不存储它们.也许是否有一种方法可以在没有睡眠的情况下使用异步事物来表达它?
我是一个初学者学习coroutines。
不完全是,但我对 a 是什么有一点了解coroutine。
这suspend function也很难,但需要一点理解。
我正在一步步学习,但有些地方我不明白。
那是suspendCoroutine。在示例代码中,suspendCoroutine和Continuation在块中使用,但我不知道这两个是什么。
我看过其他网站,但找不到任何可以轻松解释的地方。
您能简单地解释一下suspendCoroutine和 的Continuation用途吗?如果可能的话,可以举个例子吗?
Kotlin corutines是有限状态机和一些任务运行器的糖(例如,默认的ForkJoinPool).https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md#implementation-details
换句话说,java/kotlin运行时中还没有运行时协同程序(但这可以随http://cr.openjdk.java.net/~rpressler/loom/Loom-Proposal.html而改变).Kotlin协程只是连续执行的任务,它们是逐个执行的.每个任务都可以在线程池的任何线程中执行.
Go运行时支持"协同程序".但是goroutines并不是真正的协同程序.Goroutines不允许在程序中设置屈服点.此外,Go不允许设置自定义线程池.您只能在默认池中设置线程大小.
kotlin协同程序和goroutine之间的第一个区别是Go运行时管理此时正在运行的协同程序.当goroutine在某些IO操作(或同步原语)被阻塞时,请选择下一个Job来执行它.在JVM中,没有这种术语的智能工作转换.
因此,Go可以廉价地改变当前正在运行的工作.Go只需改变一些注册表https://groups.google.com/forum/#!msg/golang-nuts/j51G7ieoKh4/wxNaKkFEfvcJ.但也有人说,JVM可以使用堆栈线程而不是使用寄存器.因此根本没有保存和加载寄存器.
kotlin协程和goroutines之间的第二个区别是协同程序的类型.Kotlin协同程序是无堆栈协程.Goroutines是堆栈协程.Kotlin协程的所有状态都存储在Kotlin上下文中,该上下文存储在堆中.Goroutines状态存储在寄存器和线程堆栈中.
我想知道,哪些协程(goroutines和kotlin协程)在IO绑定任务中更快?CPU绑定任务?内存消耗怎么样?
据我所知,libgreen不再是Rust标准库的一部分.另外,我找不到一个单独的libgreen包.有一些替代方案 - coroutine,它现在不提供实际的绿色线程,而green-rs,它已被破坏.我是否理解现在在Rust中没有轻量级的Go-like进程?
我正在尝试对我的本地数据库进行后台调用,并使用协同程序使用结果更新UI.这是我的相关代码:
import kotlinx.coroutines.experimental.*
import kotlinx.coroutines.experimental.Dispatchers.IO
import kotlinx.coroutines.experimental.Dispatchers.Main
import kotlin.coroutines.experimental.CoroutineContext
import kotlin.coroutines.experimental.suspendCoroutine
class WarehousesViewModel(private val simRepository: SimRepository)
: BaseReactViewModel<WarehousesViewData>(), CoroutineScope {
private val job = Job()
override val coroutineContext: CoroutineContext
get() = job + Main
override val initialViewData = WarehousesViewData(emptyList())
override fun onActiveView() {
launch {
val warehouses = async(IO) { loadWarehouses() }.await()
updateViewData(viewData.value.copy(items = warehouses))
}
}
private suspend fun loadWarehouses(): List<Warehouse> =
suspendCoroutine {continuation ->
simRepository.getWarehouses(object : SimDataSource.LoadWarehousesCallback {
override fun onWarehousesLoaded(warehouses: List<Warehouse>) {
Timber.d("Loaded warehouses")
continuation.resume(warehouses)
}
override …Run Code Online (Sandbox Code Playgroud) 我无法理解暗示 a 的类型Coroutine。据我了解,当我们声明一个函数时,如下所示:
async def some_function(arg1: int, arg2: str) -> list:
...
Run Code Online (Sandbox Code Playgroud)
我们有效地声明了一个函数,它返回一个协程,当等待时,它返回一个列表。因此,输入提示的方法是:
f: Callable[[int, str], Coroutine[???]] = some_function
Run Code Online (Sandbox Code Playgroud)
但Coroutine泛型类型有 3 个参数!如果我们转到该typing.py文件,我们就可以看到它:
...
Coroutine = _alias(collections.abc.Coroutine, 3)
...
Run Code Online (Sandbox Code Playgroud)
还有一种Awaitable类型,从逻辑上讲,它应该是Coroutine只有一个泛型参数的父级(我想是返回类型):
...
Awaitable = _alias(collections.abc.Awaitable, 1)
...
Run Code Online (Sandbox Code Playgroud)
因此,也许以这种方式键入提示函数或多或少是正确的:
f: Callable[[int, str], Awaitable[list]] = some_function
Run Code Online (Sandbox Code Playgroud)
或者是吗?
所以,基本上,问题是:
Awaitable代替吗?Coroutineasync defCoroutine?它的用例是什么?我有这样的课
class SomeClass {
fun someFun() {
// ... Some synchronous code
async {
suspendfun()
}
}
private suspend fun suspendFun() {
dependency.otherFun().await()
// ... other code
}
}
Run Code Online (Sandbox Code Playgroud)
我想进行单元测试,someFun()所以我编写了一个单元测试,如下所示:
@Test
fun testSomeFun() {
runBlocking {
someClass.someFun()
}
// ... verifies & asserts
}
Run Code Online (Sandbox Code Playgroud)
但这似乎不起作用,因为runBlocking实际上不会阻止执行,直到runBlocking内的所有内容都完成.如果我suspendFun()直接在里面测试runBlocking它按预期工作,但我希望能够一起测试someFun().
有关如何使用同步和异步代码测试函数的任何线索?
关于协同程序(在Unity3D和其他地方)如何工作,我感到困惑和好奇.coroutine是新线程吗?他们说Unity的文档:
协程是一个可以暂停执行(yield)直到给定的YieldInstruction完成的函数.
他们在这里有C#示例:
using UnityEngine;
using System.Collections;
public class example : MonoBehaviour {
void Start() {
print("Starting " + Time.time);
StartCoroutine(WaitAndPrint(2.0F));
print("Before WaitAndPrint Finishes " + Time.time);
}
IEnumerator WaitAndPrint(float waitTime) {
yield return new WaitForSeconds(waitTime);
print("WaitAndPrint " + Time.time);
}
}
Run Code Online (Sandbox Code Playgroud)
我对这个例子有很多疑问:
在上面的例子中,哪一行是协程?是WaitAndPrint()一个协程?是WaitForSeconds()一个协程?
在这一行:yield return new WaitForSeconds(waitTime);为什么都yield和return存在?我在Unity文档中读到"yield语句是一种特殊的返回,它确保函数将在下次调用yield语句后继续执行." 如果yield是特别的return,return这里做了什么?
为什么我们要退货IEnumerator?
是否StartCoroutine开始新线程?
WaitAndPrint() …
在阅读了Eli Bendersky 关于通过Python协同程序实现状态机的文章后,我想......
我成功完成了第一部分(但是没有使用async defs或yield froms,我基本上只是移植了代码 - 所以任何改进都是最受欢迎的).
但是我需要一些关于协同程序类型注释的帮助:
#!/usr/bin/env python3
from typing import Callable, Generator
def unwrap_protocol(header: int=0x61,
footer: int=0x62,
dle: int=0xAB,
after_dle_func: Callable[[int], int]=lambda x: x,
target: Generator=None) -> Generator:
""" Simplified protocol unwrapping co-routine."""
#
# Outer loop looking for a frame header
#
while True:
byte = (yield)
frame = [] # type: List[int]
if byte == header:
#
# Capture the full frame
# …Run Code Online (Sandbox Code Playgroud) 我试图阅读有关在调用,暂停,恢复和终止协程函数时调用的操作顺序的文档(功能部件本身的cppreference和标准文档)。该文档深入概述了各种扩展点,这些扩展点允许库开发人员使用库组件自定义协程的行为。从高级的角度来看,这种语言功能似乎是经过深思熟虑的。
不幸的是,我在遵循协程执行机制方面确实很难,而且作为图书馆开发人员,我如何使用各种扩展点来定制所述协程的执行。甚至从哪里开始。
我不完全了解的新定制点集中包含以下功能:
initial_suspend()return_void()return_value()await_ready()await_suspend()await_resume()final_suspend()unhandled_exception()有人可以在高级伪代码中描述运行用户协程时编译器生成的代码吗?在抽象的层面,我想弄清楚的时候功能,如await_suspend,await_resume,await_ready,await_transform,return_value,等叫,他们所服务的目的是什么,我怎么可以用它们来写协同程序库。
不确定这是否是题外话,但是这里的一些入门资源对于整个社区来说都是非常有用的。像在cppcoro中一样四处搜寻并深入研究库实现并不能帮助我克服最初的障碍:(
coroutine ×10
kotlin ×4
python ×3
android ×1
async-await ×1
asynchronous ×1
c# ×1
c++ ×1
c++20 ×1
callback ×1
generator ×1
go ×1
goroutine ×1
iterator ×1
mypy ×1
rust ×1
suspend ×1
type-hinting ×1
unit-testing ×1