Kotlin - 协程未按预期运行
Kotlin - Coroutines not behaving as expected
这个问题与我之前的一个问题有关:。
所以,这是我当前的实现:
fun propagate() = runBlocking {
logger.info("Propagating objectives...")
val variablesWithSetObjectives: List<ObjectivePropagationMapping> =
variables.filter { it.variable.objective != Objective.NONE }
variablesWithSetObjectives.forEach { variableWithSetObjective ->
logger.debug("Propagating objective ${variableWithSetObjective.variable.objective} from variable ${variableWithSetObjective.variable.name}")
val job: Job = launch {
propagate(variableWithSetObjective, variableWithSetObjective.variable.objective, this, variableWithSetObjective)
}
job.join()
traversedVariableNames.clear()
}
logger.info("Done")
}
private tailrec fun propagate(currentVariable: ObjectivePropagationMapping, objectiveToPropagate: Objective, coroutineScope: CoroutineScope, startFromVariable: ObjectivePropagationMapping? = null) {
if (traversedVariableNames.contains(currentVariable.variable.name)) {
logger.debug("Detected loopback condition, stopping propagation to prevent loop")
return
}
traversedVariableNames.add(currentVariable.variable.name)
val objectiveToPropagateNext: Objective =
if (startFromVariable != currentVariable) {
logger.debug("Propagating objective $objectiveToPropagate to variable ${currentVariable.variable.name}")
computeNewObjectiveForVariable(currentVariable, objectiveToPropagate)
}
else startFromVariable.variable.objective
logger.debug("Choosing variable to propagate to next")
val variablesToPropagateToNext: List<ObjectivePropagationMapping> =
causalLinks
.filter { it.toVariable.name == currentVariable.variable.name }
.map { causalLink -> variables.first { it.variable.name == causalLink.fromVariable.name } }
if (variablesToPropagateToNext.isEmpty()) {
logger.debug("Detected end of path, stopping propagation...")
return
}
val variableToPropagateToNext: ObjectivePropagationMapping = variablesToPropagateToNext.random()
logger.debug("Chose variable ${variableToPropagateToNext.variable.name} to propagate to next")
if (variablesToPropagateToNext.size > 1) {
logger.debug("Detected split condition")
variablesToPropagateToNext.filter { it != variableToPropagateToNext }.forEach {
logger.debug("Launching child thread for split variable ${it.variable.name}")
coroutineScope.launch {
propagate(it, objectiveToPropagateNext, this)
}
}
}
propagate(variableToPropagateToNext, objectiveToPropagateNext, coroutineScope)
}
我目前运行算法基于以下变量拓扑(请注意,该算法遵循到达变量的箭头,而不是离开变量的箭头):
目前我得到以下调试打印结果:https://pastebin.com/ya2tmc6s。
如您所见,即使我启动协程,它们也不会开始执行,直到主传播递归函数完成对完整路径的探索。
我希望启动的协程立即开始执行...
除非另有说明,否则您在 runBlocking
中启动的所有协程都将 运行 在同一线程上。
如果要启用多线程,只需将其更改为runBlocking(Dispatchers.Default)
即可。我只是假设所有代码都是线程安全的。
如果你真的不想启用多线程,那么你真的不应该关心协程 运行 中的顺序。
这个问题与我之前的一个问题有关:
所以,这是我当前的实现:
fun propagate() = runBlocking {
logger.info("Propagating objectives...")
val variablesWithSetObjectives: List<ObjectivePropagationMapping> =
variables.filter { it.variable.objective != Objective.NONE }
variablesWithSetObjectives.forEach { variableWithSetObjective ->
logger.debug("Propagating objective ${variableWithSetObjective.variable.objective} from variable ${variableWithSetObjective.variable.name}")
val job: Job = launch {
propagate(variableWithSetObjective, variableWithSetObjective.variable.objective, this, variableWithSetObjective)
}
job.join()
traversedVariableNames.clear()
}
logger.info("Done")
}
private tailrec fun propagate(currentVariable: ObjectivePropagationMapping, objectiveToPropagate: Objective, coroutineScope: CoroutineScope, startFromVariable: ObjectivePropagationMapping? = null) {
if (traversedVariableNames.contains(currentVariable.variable.name)) {
logger.debug("Detected loopback condition, stopping propagation to prevent loop")
return
}
traversedVariableNames.add(currentVariable.variable.name)
val objectiveToPropagateNext: Objective =
if (startFromVariable != currentVariable) {
logger.debug("Propagating objective $objectiveToPropagate to variable ${currentVariable.variable.name}")
computeNewObjectiveForVariable(currentVariable, objectiveToPropagate)
}
else startFromVariable.variable.objective
logger.debug("Choosing variable to propagate to next")
val variablesToPropagateToNext: List<ObjectivePropagationMapping> =
causalLinks
.filter { it.toVariable.name == currentVariable.variable.name }
.map { causalLink -> variables.first { it.variable.name == causalLink.fromVariable.name } }
if (variablesToPropagateToNext.isEmpty()) {
logger.debug("Detected end of path, stopping propagation...")
return
}
val variableToPropagateToNext: ObjectivePropagationMapping = variablesToPropagateToNext.random()
logger.debug("Chose variable ${variableToPropagateToNext.variable.name} to propagate to next")
if (variablesToPropagateToNext.size > 1) {
logger.debug("Detected split condition")
variablesToPropagateToNext.filter { it != variableToPropagateToNext }.forEach {
logger.debug("Launching child thread for split variable ${it.variable.name}")
coroutineScope.launch {
propagate(it, objectiveToPropagateNext, this)
}
}
}
propagate(variableToPropagateToNext, objectiveToPropagateNext, coroutineScope)
}
我目前运行算法基于以下变量拓扑(请注意,该算法遵循到达变量的箭头,而不是离开变量的箭头):
目前我得到以下调试打印结果:https://pastebin.com/ya2tmc6s。
如您所见,即使我启动协程,它们也不会开始执行,直到主传播递归函数完成对完整路径的探索。
我希望启动的协程立即开始执行...
除非另有说明,否则您在 runBlocking
中启动的所有协程都将 运行 在同一线程上。
如果要启用多线程,只需将其更改为runBlocking(Dispatchers.Default)
即可。我只是假设所有代码都是线程安全的。
如果你真的不想启用多线程,那么你真的不应该关心协程 运行 中的顺序。