在Kotlin协程上运行阻塞CPU绑定的任务

时间:2019-08-31 12:23:29

标签: multithreading kotlin parallel-processing blocking coroutine

我一直在试验Kotlin,并在kotlin协程上运行阻塞CPU任务。当诸如大型CPU密集型计算之类的事情阻塞时,我们实际上并没有暂停,而是需要在不同的线程上启动事物并使它们并行运行。

我设法使以下代码与async + Default调度程序一起按预期工作,但想知道它是否可以与withContext一起使用,但没有。

fun cpuBlockingTasks() = runBlocking {
    val time = measureTimeMillis {
        val t1 = cpuTask(id = 1, blockTime = 500)
        val t2 = cpuTask(id = 2, blockTime = 2000)
        println("The answer is ${t1 + t2}")
    }
    println("Time taken: $time")
}
suspend fun cpuTask(id: Int, blockTime: Long): Int = withContext(Dispatchers.Default) {
    println("work $id start ${getThreadName()}")
    val res = doSomeCpuIntensiveTask(blockTime)
    println("work $id end ${getThreadName()}")
    res
}
fun doSomeCpuIntensiveTask(time: Long): Int {
    Thread.sleep(time) // to mimick actual thread blocking / cpu work
    return 1
}

此代码在> 2500毫秒内完成,并顺序在同一线程上运行。我原以为它会在一个线程中启动第一个协程,立即返回到调用方,并在另一个线程中启动第二个协程,但是那样就不起作用了。任何人都知道为什么会这样,以及如何在不使用调用程序函数中启动async协程的情况下进行修复?

这是输出

work 1 start ForkJoinPool.commonPool-worker-5 @coroutine#1
work 1 end ForkJoinPool.commonPool-worker-5 @coroutine#1
work 2 start ForkJoinPool.commonPool-worker-5 @coroutine#1
work 2 end ForkJoinPool.commonPool-worker-5 @coroutine#1
The answer is 2
Time taken: 2523

1 个答案:

答案 0 :(得分:1)

您没有在31 Aug 2019 cpuTask 1中创建新的协程。您只是在切换上下文。可以使用cpuTask 2轻松修复:

async