在Kotlin的协程中挂起IO绑定和CPU绑定功能

时间:2019-05-06 17:14:32

标签: kotlin kotlin-coroutines

在协程中执行IO绑定功能(例如,从后端请求数据)为我提供了在执行请求结果可用之前中止其执行的优势,对吗?但是,CPU绑定功能(例如,解析一个巨大的文本文件)不会“等待”任何东西,它只会做很多工作。那么,在协程内部执行它是否没有给我带来暂停执行的好处?在涉及CPU的函数方面,协程唯一给我的(宝贵的)优势是能够选择执行该函数时将被阻塞的线程(或线程池),对吗?

2 个答案:

答案 0 :(得分:2)

  

那么,在协程内部执行它不会给我带来暂停执行的好处吗?

我不确定我理解您的意思,但是无论您选择哪种调度程序,调用暂停函数无论如何都会暂停调用协程,而就我所知,这并不取决于函数内部的内容。 / p>

但是,请注意,从协程内部调用 blocking 函数会使该协程阻塞执行该线程的线程,这里没有任何魔术。这就是为什么应避免在协程内部进行阻塞操作。

  

协程在给CPU绑定的函数上唯一(有价值的)优势是能够选择执行函数时将被阻塞的线程(或线程池),对吗?

使用Dispachers.IODispatchers.Default仅具有选择其他线程池的作用,是的。

对于IO,该池将产生所需数量的线程,因为它们都可以“在I / O上阻塞”。

Default的情况下,将仅创建与内核数量成比例的多个线程,因为与CPU绑定的任务创建的线程多于内核是没有意义的(如果所有内核)忙,那么上下文切换只会降低整体性能。

答案 1 :(得分:2)

挂起函数不会自动使该函数不阻塞线程,在以下情况下,因为它仍会阻塞调用线程(与用于启动协程的范围相关联的分派器)

suspend fun findBigPrime(): BigInteger = 
    BigInteger.probablePrime(4096, Random())
可以使用withContext将

悬浮函数变成非阻塞线程函数,

suspend fun findBigPrime(): BigInteger =
    withContext(Dispatchers.Default) {
        BigInteger.probablePrime(4096, Random())
    }

这会导致从主线程/调用者线程启动的协程被阻塞,而不是线程本身被阻塞。

https://medium.com/@elizarov/blocking-threads-suspending-coroutines-d33e11bf4761