早上好,我发现使用协程的库内部的延迟要比传递的值多得多(这是5000毫秒,但往往需要长达20秒)我最初假设一些库内部问题,这是导致继续不能按时调用..但我无法找到这个“问题”,改变了范围调度程序,以unconfined在库中没有改变什么,而且所有内核的CPU使用率都很低(5%),因此我使用该库的coroutineContext进行了一些测试。
存储库上下文为:BLACKBOX_ACTOR.coroutineContext
val threadPool = Executors.newFixedThreadPool(10)
fun busyCoreDelay(ms:Int){ // CONF WORKS ALWAYS
val tstart=System.currentTimeMillis()
while(System.currentTimeMillis()-tstart<ms){
//noop
}
}
withContext( CoroutineName("Test") + Job() +Dispatchers.Unconfined){
GlobalScope.launch(BLACKBOX_ACTOR.coroutineContext+ Job() + Dispatchers.IO+CoroutineName("Test2") ){ // AA with this DOESNTWORKS
//GlobalScope.launch(CoroutineName("Test3") + Job() +Dispatchers.Unconfined){ // AB with this WORKS (only if AA is not present!)
GlobalScope.launch(CoroutineName("Test3") + Job() +threadPool.asCoroutineDispatcher()){ // AC (works with AB , doesn't with AA )
while(isActive){
val tstart=System.currentTimeMillis()
//delay(5000) // PROBLEM1
busyCoreDelay(5000)
val tend=System.currentTimeMillis()
val delaydelta=tend-tstart
log.warn { "inner delaydelta = ${delaydelta}" }
}
}
}
//
}
主要问题是为什么即使父进程在非受限Dispatchers中,delay也会超过标称值(这是在库内部,代码在此处发布很复杂,但非受限Dispatchers不应避免delay()调用占用太多时间(给定cpu几乎为0?)
而且......为什么我调用“delay(5000)//PROBLEM 1”时AA + AB or AA+AC
不起作用,而用// AB or AB+AC
起作用?
据我所知,内部作业应该从BLACKBOX_ACTOR中转义任何父协程上下文和调度程序(busyCoreDelay始终适用于所有配置)
非常感谢
1条答案
按热度按时间iqjalb3h1#
找到了!问题是从一个(我的)内部库中使用
Dispatchers.Unconfined
,这导致代码在kotlinx.coroutines.DefaultExecutor上执行,一旦任何代码在kotlinx.coroutines.DefaultExecutor
上运行,延迟就会变得“不稳定”(考虑到在其他代码正在执行时没有到达延续点,它显然无法按时调度)这触发了其它库中的错误行为,使上游调用超时等等。
现在,我将把答案标记为已完成,因为问题实际上是我的错误,没有注意到
Dispatchers.Unconfined
的使用(启用最大日志级别,并在程序日志中查找在
kotlinx.coroutines.DefaultExecutor
上执行的代码)我希望它对其他遇到同类问题的人也会有用,
我还要感谢所有对原问题提出评论的人。