首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Kotlin协程上运行阻塞CPU限制的任务

在Kotlin协程上运行阻塞CPU限制的任务
EN

Stack Overflow用户
提问于 2019-08-31 20:23:29
回答 1查看 663关注 0票数 3

我一直在试验Kotlin,并在kotlin协程上运行阻塞CPU任务。当程序阻塞时,比如大的cpu密集型计算,我们并不是真的挂起,而是需要在不同的线程上启动程序,让它们并行运行。

我设法让下面的代码在async + Default dispatcher下正常工作,但我想知道它是否能与withContext一起工作,但它没有。

代码语言:javascript
复制
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")
}
代码语言:javascript
复制
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
}
代码语言:javascript
复制
fun doSomeCpuIntensiveTask(time: Long): Int {
    Thread.sleep(time) // to mimick actual thread blocking / cpu work
    return 1
}

此代码在>2500ms内完成,并在同一线程上按顺序运行。我期望它在线程中启动第一个协程,立即返回到调用者,并在不同的线程上启动第二个协程,但并不是这样工作的。有人知道为什么会出现这种情况,以及如何在不在调用者函数中启动async协程的情况下修复它?

这就是输出

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

发布于 2019-08-31 20:51:34

您没有在cpuTask 1cpuTask 2中创建新的协程。您只是在切换上下文。可以使用async轻松修复此问题

代码语言:javascript
复制
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
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57737998

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档