在协程中执行IO绑定功能(例如,从后端请求数据)为我提供了在执行请求结果可用之前中止其执行的优势,对吗?但是,CPU绑定功能(例如,解析一个巨大的文本文件)不会“等待”任何东西,它只会做很多工作。那么,在协程内部执行它是否没有给我带来暂停执行的好处?在涉及CPU的函数方面,协程唯一给我的(宝贵的)优势是能够选择执行该函数时将被阻塞的线程(或线程池),对吗?
答案 0 :(得分:2)
那么,在协程内部执行它不会给我带来暂停执行的好处吗?
我不确定我理解您的意思,但是无论您选择哪种调度程序,调用暂停函数无论如何都会暂停调用协程,而就我所知,这并不取决于函数内部的内容。 / p>
但是,请注意,从协程内部调用 blocking 函数会使该协程阻塞执行该线程的线程,这里没有任何魔术。这就是为什么应避免在协程内部进行阻塞操作。
协程在给CPU绑定的函数上唯一(有价值的)优势是能够选择执行函数时将被阻塞的线程(或线程池),对吗?
使用Dispachers.IO
或Dispatchers.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