multithreading - 在 Kotlin 协程上运行阻塞的 CPU 绑定(bind)任务

标签 multithreading kotlin parallel-processing blocking coroutine

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

我设法使以下代码与 async + Default dispatcher 一起按预期工作,但想知道它是否可以与 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

最佳答案

您没有在 cpuTask 1cpuTask 2 中创建新协程。您只是在切换上下文。它可以很容易地用 async 修复:

fun cpuBlockingTasks() = runBlocking {
    val time = measureTimeMillis {
        val t1 = async { cpuTask(id = 1, blockTime = 500) }
        val t2 = async { cpuTask(id = 2, blockTime = 2000) }
        println("The answer is ${t1.await() + t2.await()}")
    }
    println("Time taken: $time") // Time taken: 2026
}

关于multithreading - 在 Kotlin 协程上运行阻塞的 CPU 绑定(bind)任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57737998/

相关文章:

Kotlin:如何在字符串中交换字符

java - 如何从 Kotlin/Java 中运行 Kotlin-Script (.kts) 文件?

android - 使用 Kotlin 创建 Android 振动器

C# 并行库、XmlReader、XmlWriter

java - 在不阻塞整个数组的情况下更新数组元素

c++ - 在流水线执行中使用并行性

c# - 线程卡在 MySqlCommand.ExecuteNonQuery() 中

multithreading - 在多个线程中超出范围运行函数

python - 在 Python 中运行批量同步并行模型 (BSP)

c++ - std::sort 比自定义 OpenMP 并行排序算法快得多