Tag: 协程

监制器内的生产者

我正在尝试为听众创建producer 。 我的代码看起来像这样 suspend fun foo() = produce{ someEvent.addListener { this.send(it) } } 但是我得到错误Suspension functions can be called only within coroutine中Suspension functions can be called only within coroutine ,这是有道理的。 我的问题是。 有没有办法使用协程来实现这个模式?

扇出/扇入结果通道

我正在生产项目,从多个协同例程中消费,并推回到resultChannel。 制片人正在关闭最后一个项目后的频道。 代码永远不会结束,因为resultChannel永远不会被关闭。 如何检测并正确完成迭代,所以hasNext()返回false ? val inputData = (0..99).map { "Input$it" } val threads = 10 val bundleProducer = produce<String>(CommonPool, threads) { inputData.forEach { item -> send(item) println("Producing: $item") } println("Producing finished") close() } val resultChannel = Channel<String>(threads) repeat(threads) { launch(CommonPool) { bundleProducer.consumeEach { println("CONSUMING $it") resultChannel.send("Result ($it)") } } } val iterator = object […]

用Java实现协程

这个问题与我在Java中的现有协程实现的问题有关。 如果我猜想,现在没有完全实现Java中现有的协程,那么实现它们需要什么? 正如我在这个问题中所说的,我知道以下几点: 你可以在后台实现“协程”作为线程/线程池。 您可以在后台使用JVM字节码做一些棘手的事情,以使协程成为可能。 所谓的“达芬奇机器”JVM实现具有原语,使得协程可以不用字节码操作。 有许多基于JNI的协程也是可能的。 我将依次解决每个人的缺陷。 基于线程的协程 这个“解决方案”是病态的。 协程的整个目的是避免线程,锁定,内核调度等开销。协程应该是轻快的,只能在用户空间中执行。 在全倾斜线程严格限制的条件下实现它们,摆脱了所有的优点。 JVM字节码操作 这个解决方案更实用,虽然有点难以实现。 这与C语言中的协程库(这是其中的多少个工作)跳到汇编语言中大致相同,其优点是只有一个架构需要担心和正确。 它还将您绑定到只在完全兼容的JVM堆栈上运行代码(这意味着,例如,没有Android),除非您可以找到一种方法在不兼容的堆栈上执行相同的操作。 但是,如果您确实找到了一种方法,那么现在您的系统复杂性和测试需求已经翻了一番。 达芬奇机器 达芬奇机器对于实验来说是很酷的,但是由于它不是一个标准的JVM,它的功能在任何地方都不可能实现。 事实上,我怀疑大多数生产环境都会特别禁止使用达芬奇机器。 因此,我可以用这个来做一些很酷的实验,但是不能用于我想要发布到真实世界的任何代码。 这也有类似上面的JVM字节码操作解决方案的附加问题:不会在替代堆栈(如Android的)上工作。 JNI的实现 这个解决方案使得在Java中这样做是毫无意义的。 CPU和操作系统的每个组合都需要独立测试,每个组合都有可能使微妙的失败成为可能。 另外,当然,我可以把自己完全绑定到一个平台上,但是这也使得Java中的事情完全没有意义。 所以… 有没有什么办法可以在没有使用这四种技术的Java中实现协程? 或者我会被迫使用那些味道最少的四个之一(JVM操作)呢? 编辑添加: 只是为了确保混淆,这是我的另一个 相关问题,但不是相同的。 那个正在寻找一个现有的实施,以避免不必要的重新发明车轮。 这个问题是关于如果另一个证明无法回答的话,如何去执行Java中的协程。 目的是在不同的线程上保留不同的问题。

协程(goroutines和kotlin协程)哪个更快?

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协程和goroutines之间的第一个区别是Go运行时管理此时正在运行的协程。 当某个IO操作(或同步原语)阻塞了goroutine时,选择下一个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绑定任务? 内存消耗如何?

什么关闭kotlinx.coroutines通道呢

使用channel.close()关闭kotlinx.coroutines频道的是什么,以及不手动关闭频道的负面影响是什么? 如果我不手动关闭一个频道会有一些不必要的处理? 会不会有某个地方的频道被引用,以防止它成为GCd? 还是关闭功能只是作为通知潜在用户不能再使用频道的一种方式而存在。 (从Kotlin论坛转贴的问题https://discuss.kotlinlang.org/t/closing-coroutine-channels/2549 )

在Kotlin协同程序中启动/连接和异步/等待之间有什么区别?

在kotlinx.coroutines库中,您可以使用launch (使用kotlinx.coroutines )或async (使用await )来启动新协程。 他们有什么区别?

在Kotlin协程被取消之后,抛不出异常抛出

使用kotlinx.coroutines lib如果在协程被取消后抛出异常,我不能捕捉到异常。 这导致应用程序崩溃。 fun foo() { val job = launch(UI) { try { Log.d("TAG", "Start coroutine") run(CommonPool) { Log.d("TAG", "Start bg task") // Intentionally make bg task running for a long time SystemClock.sleep(2000) Log.d("TAG", "Throw bg task exception") throw RuntimeException("Bg task exception") } } catch (e: Exception) { Log.e("TAG", "Handle coroutine exception", e) } } […]

为什么在Kotlin中使用方法引用来暂停函数是不可能的?

我有一个Job实例列表,我想在启动后的某个时候取消。 这看起来如下: val jobs = arrayListOf<Job>() //launch and add jobs… jobs.forEach { it.cancelAndJoin() } // cancels the jobs and waits for completion 不幸的是,这里不可能使用方法引用。 原因: cancelAndJoin是一个suspend函数,因为编译器抱怨: jobs.forEach (Job::cancelAndJoin) “错误:(30,24)Kotlin:不支持[可调参考暂停功能]” 为什么这不工作? (fyi代码在另一个协程中执行)

如何使用基于ThreadLocal和Kotlin协程的代码

一些JVM框架使用ThreadLocal来存储应用程序的调用上下文,如SLF4j MDC ,事务管理器,安全管理器等。 但是,Kotlin协同程序是在不同的线程上发送的,所以如何才能工作呢? (这个问题受GitHub问题的启发)

Kotlin可以替代Python的协同产出和发送

什么是一个Kotlin惯用的替代下面的Python协程代码片段: def generator(): c = 1 while True: op = yield c if op == 'inc': c += 1 elif op == 'mult': c *= 2 # main g = generator() a = g.send(None) # start b = g.send('inc') c = g.send('mult') d = g.send('inc') print([a, b, c, d]) # 1, 2, 4, 5 所以我需要从协程(通过通道?)获取值,而且还要将值发送回协程。 […]