Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asynchronous 两个协同程序同时调用一个函数两次_Asynchronous_Kotlin_Coroutine_Kotlin Coroutines_Simultaneous - Fatal编程技术网

Asynchronous 两个协同程序同时调用一个函数两次

Asynchronous 两个协同程序同时调用一个函数两次,asynchronous,kotlin,coroutine,kotlin-coroutines,simultaneous,Asynchronous,Kotlin,Coroutine,Kotlin Coroutines,Simultaneous,如何通过两个协同程序同时运行一个函数两次? 我尝试使用以下代码: import kotlinx.coroutines.* fun main() = runBlocking<Unit> { launch { calculate("first") } launch { calculate("second") } } fun calculate(name: String) { var value = 0 f

如何通过两个协同程序同时运行一个函数两次? 我尝试使用以下代码:

import kotlinx.coroutines.*

fun main() = runBlocking<Unit> {
    launch {
        calculate("first")
    }
    launch {
        calculate("second")
    }
}

fun calculate(name: String) {
    var value = 0
    for (x in 1..1_000){
        value += 1
        if(x % 100 == 0){
            println("calculating $x for $name")
        }
    }
}
导入kotlinx.coroutines*
fun main()=运行阻塞{
发射{
计算(“第一次”)
}
发射{
计算(“秒”)
}
}
趣味计算(名称:字符串){
var值=0
用于(1..1_000中的x){
值+=1
如果(x%100==0){
println(“为$name计算$x”)
}
}
}
但第二个协同路由要等到第一个协同路由离开函数后才能运行它


我该怎么做呢?

协同程序调度程序不能在代码的任何地方从一个协同程序跳到另一个协同程序(就像线程一样)。一次调用协同路由中的所有非挂起(阻塞)代码,并且只有当协同路由挂起时,dispatcher才能让另一个协同路由在同一线程中执行其工作

这意味着您的函数
calculate
必须在某些点挂起您的协同程序-对于您的情况,您应该调用挂起函数
yield()
,例如,在循环的每次迭代之后。此函数将生成一个协程调度器线程,以运行其他协程

suspend fun calculate(name: String) {
    var value = 0
    for (x in 1..1_000){
        value += 1
        if(x % 100 == 0){
            println("calculating $x for $name")
        }
        yield()
    }
}

runBlocking
使用事件循环作为协程调度器的默认值。对于事件循环,只有一个协同程序可以同时在事件线程上运行

fun main() = runBlocking<Unit>(Dispatchers.Default) {
    launch {
        calculate("first")
    }
    launch {
        calculate("second")
    }
}
您可以指定使用线程池的任何其他调度程序,例如
Dispatchers.Default
,以同时运行协同路由

fun main() = runBlocking<Unit>(Dispatchers.Default) {
    launch {
        calculate("first")
    }
    launch {
        calculate("second")
    }
}
fun main()=运行阻塞(Dispatchers.Default){
发射{
计算(“第一次”)
}
发射{
计算(“秒”)
}
}

由于要并行化的代码不可挂起,因此没有充分的理由使用协同路由。基本上,您使用整个协同路由机制只是为了将作业发送到线程池,并强制调用方建立协同路由范围

相反,您可以将任务提交给
IO
dispatcher下面的执行者:

fun main() {
    Dispatchers.IO.asExecutor().apply {
        execute { calculate("first") }
        execute { calculate("second") }
    }
}

我认为与@Rene方法相比,这种方法需要一些更复杂的样板文件来防止主函数或jvm在工作完成之前结束,对吗?是的,这是真的。尽管如此,对于我来说,为纯粹的执行者服务工作而参与合作项目还是有点落后,但这可能是今天在科特林最方便的方式。