gpt4 book ai didi

kotlin - 从coroutineScope内部创建actor会阻塞线程,但是与CoroutineScope扩展函数创建的actor却不同

转载 作者:行者123 更新时间:2023-12-02 13:26:57 24 4
gpt4 key购买 nike

我正在尝试与Kotlin中的 Actor 生成器构造一起玩。我已经编写了以下代码来发送和接收来自 Actor 的消息。

package com.byteobject.prototype.kotlin

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.actor
import kotlinx.coroutines.channels.consumeEach

class GreetingsMessage(val to: String, val greetings: CompletableDeferred<String>)

fun CoroutineScope.newGreeter(greet: String) = actor<GreetingsMessage> {
channel.consumeEach {
it.greetings.complete("$greet ${it.to}")
}
}

fun main() {
runBlocking {
val greeter = newGreeter("Hello")
val greetingsMessage = GreetingsMessage("World", CompletableDeferred())
launch(Dispatchers.Default) {
greeter.send(greetingsMessage)
}
launch(Dispatchers.Default) {
println(greetingsMessage.greetings.await())
greeter.close()
}
}
}
此代码按预期工作。
但是下面的代码不是,因为它正在挂程序。
package com.byteobject.prototype.kotlin

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.actor
import kotlinx.coroutines.channels.consumeEach

class GreetingsMessage(val to: String, val greetings: CompletableDeferred<String>)

suspend fun newGreeter(greet: String) = coroutineScope {
actor<GreetingsMessage> {
channel.consumeEach {
it.greetings.complete("$greet ${it.to}")
}
}
}

fun main() {
runBlocking {
val greeter = newGreeter("Hello")
val greetingsMessage = GreetingsMessage("World", CompletableDeferred())
launch(Dispatchers.Default) {
greeter.send(greetingsMessage)
}
launch(Dispatchers.Default) {
println(greetingsMessage.greetings.await())
greeter.close()
}
}
}
通过将newGreeter函数用作暂停函数并通过coroutineScope封闭该函数,对代码进行了少许修改,对newGreeter方法的调用将阻塞线程并挂起程序。我相信newGreeter作为CoroutineScope的扩展功能和包含在coroutineScope中的暂停功能应该完全相同。
我想知道两种方法之间的区别,以及第二种方法为什么要挂程序。
我尝试过使用Produce函数进行相同的操作,并且在这里我还发现了调用suspend function来获取ReceieveChannel阻塞了线程,而用作扩展函数的相同Produce结构按预期工作
该代码是非阻塞的
package com.byteobject.prototype.kotlin

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.produce
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

fun CoroutineScope.produceIntegers(n: Int) = produce<Int> {
for (i in 1..n)
send(i)
close()
}

fun main() {
runBlocking {
val intChan = produceIntegers(10)
launch {
for (i in intChan)
println(i)
}
}
}
因为这阻塞了对generateIntegers方法的调用
package com.byteobject.prototype.kotlin

import kotlinx.coroutines.channels.produce
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

suspend fun produceIntegers(n: Int) = coroutineScope {
produce<Int> {
for (i in 1..n)
send(i)
close()
}
}

fun main() {
runBlocking {
val intChan = produceIntegers(10)
launch {
for (i in intChan)
println(i)
}
}
}

最佳答案

问题在于coroutineScope { } 创建了一个新的阻塞范围(结构化并发)-等待所有已启动的协程完成。
另请:https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/coroutine-scope.html

this function returns as soon as the given block and all its children coroutines are completed.


另一方面,扩展功能仅使用上下文(接收方)中的协程镜。

关于kotlin - 从coroutineScope内部创建actor会阻塞线程,但是与CoroutineScope扩展函数创建的actor却不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63351223/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com