当容量小于消息数时,Kotlin actors进入死锁
我想把阿克卡演员和科特林演员作为基准。对kotlin有了一些基本的了解,我试着用乒乓球做了一个简单的测试,结果程序卡住了。只有当我使容量大小和消息数量相同时,它才进展到完成。据我理解,两个行动者都应继续开展工作,而不应依赖能力当容量小于消息数时,Kotlin actors进入死锁,kotlin,Kotlin,我想把阿克卡演员和科特林演员作为基准。对kotlin有了一些基本的了解,我试着用乒乓球做了一个简单的测试,结果程序卡住了。只有当我使容量大小和消息数量相同时,它才进展到完成。据我理解,两个行动者都应继续开展工作,而不应依赖能力 import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.SendChannel im
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.SendChannel
import kotlinx.coroutines.channels.actor
import kotlinx.coroutines.runBlocking
sealed class Message
class Ping(val replyTo: SendChannel<Message>) : Message()
object Pong : Message()
object Start : Message()
fun CoroutineScope.PingActor() = actor<Message>(capacity = 10) {
for (msg in channel) {
when (msg) {
is Ping ->
msg.replyTo.send(Pong)
}
}
}
fun CoroutineScope.PongActor(pinger: SendChannel<Message>, count: Int, done: CompletableDeferred<Unit>) =
actor<Message> (capacity = 10){
var counter = count
for (msg in channel) {
when (msg) {
is Start ->
for (i in 1..count) {
pinger.send(Ping(this.channel))
}
is Pong -> {
counter -= 1
if (counter == 0) {
done.complete(Unit)
}
}
}
}
}
fun main() = runBlocking<Unit> {
val response = CompletableDeferred<Unit>()
val pinger = PingActor()
val ponger = PongActor(pinger, 100, response)
val startTime = System.nanoTime()
ponger.send(Start)
response.await()
println("total time taken is ${System.nanoTime() - startTime}")
pinger.close()
ponger.close()
}
导入kotlinx.coroutines.CompletableDeferred
导入kotlinx.coroutines.CoroutineScope
导入kotlinx.coroutines.channels.SendChannel
导入kotlinx.coroutines.channels.actor
导入kotlinx.coroutines.runBlocking
密封类消息
类Ping(val replyTo:SendChannel):Message()
对象Pong:Message()
对象开始:消息()
fun CoroutineScope.PingActor()=参与者(容量=10){
对于(通道中的msg){
何时(味精){
是Ping->
msg.replyTo.send(Pong)
}
}
}
PongActor(pinger:SendChannel,count:Int,done:CompletableDeferred)=
演员(容量=10){
变量计数器=计数
对于(通道中的msg){
何时(味精){
是开始->
对于(1.计数中的i){
pinger.send(Ping(this.channel))
}
是庞->{
计数器-=1
如果(计数器==0){
完成。完成(单位)
}
}
}
}
}
fun main()=运行阻塞{
val响应=CompletableDeferred()
val pinger=PingActor()
val ponger=PongActor(pinger,100,响应)
val startTime=System.nanoTime()
ponger.send(启动)
response.wait()
println(“所花费的总时间为${System.nanoTime()-startTime}”)
pinger.close()
ponger.close()
}
只有当我使容量大小和消息数量相同时,它才进展到完成
您可以检查50个容量(对于两个演员)是否足够。让我们看看10会发生什么:
pinger
接收Start
消息pinger
尝试向ponger
发送100条消息。发送10个,第11个块,直到队列中有更多空间李>
ponger
处理消息并发送10条回复pinger
现在可以再发送10条消息ponger
尝试处理第11次Ping
,但在发送回复时会被阻止,因为pinger
的邮箱中有10条消息请注意,
pinger
无法处理回复,因为它仍在处理Start
消息 谢谢。因此,如果我不能提前知道消息的数量,那么我需要使用无限容量,或者改变逻辑。例如,在普通乒乓球比赛中,你只会立即发送第一个乒乓球,其余的都是回复乒乓球。这样你就不会遇到这个问题了。