我不确定该yield功能的目的是什么。
你能检查我有这个例子吗?
无论如何,我在这里跟随一个例子。
这是代码:
val job = launch {
val child = launch {
try {
delay(Long.MAX_VALUE)
} finally {
println("Child is cancelled")
}
}
yield() //why do i need this ???????
println("Cancelling child")
child.cancel()
child.join()
yield()
println("Parent is not cancelled")
}
job.join()
Run Code Online (Sandbox Code Playgroud)
当我注释掉第一个收益率时,我得到以下结果:
取消孩子
父母未取消
但是如果我保持原样,我会得到:
取消孩子
儿童被取消
父母未取消
yield在这里使用是什么意思?
Xua*_*yen 21
我会在四个相关的事情的背景下回答这个问题:
yield(value: T)完全无关yield()isActive只是一个标志,用于识别协程是否仍处于活动状态或已取消。您可以定期检查此标志并决定停止当前协程或继续。当然,通常情况下,我们只有在是的情况下才继续true。否则不要运行任何东西或抛出异常,例如。CancellationException。ensureActive()检查isActive上面的标志,CancellationException如果是 则抛出false。yield()不仅首先调用ensureActive(),而且还礼貌地告诉同一个调度程序中的其他协程:“嘿,你们先走,然后我继续。” 原因可能是“目前我的工作没那么重要”。或者“很抱歉屏蔽你们这么久。我不是一个自私的人,所以现在轮到你们了。” 您可以完全按照字典中的含义来理解:“屈服(给某人/某物):允许较大道路上的车辆先行。” 同义词:让路。Yur*_*mke 16
https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/yield.html
将当前协程调度程序的线程(或线程池)交给其他协程运行。如果协程调度器没有自己的线程池(如 Dispatchers.Unconfined),那么这个函数什么都不做,而是检查协程作业是否完成。该暂停功能是可以取消的。如果当前协程的 Job 在调用此挂起函数时或此函数等待调度时被取消或完成,则它会以 CancellationException 恢复。
它至少完成了几件事
Abh*_*kar 16
@Vasile 的答案与问题最相关,@Yuri Schimke 接受的答案只是一般信息,实际上并没有回答问题。
为了说明第一个的必要性yield,让我们稍微更改一下代码,添加两个“ * is running ”语句:
val job = launch {
val child = launch {
try {
println("Child is running")
delay(Long.MAX_VALUE)
} finally {
println("Child is cancelled")
}
}
yield() // without this, child job doesn't get executed
println("Cancelling child")
child.cancel()
child.join()
yield()
println("Parent is not cancelled")
}
println("Parent is running")
job.join()
Run Code Online (Sandbox Code Playgroud)
输出:
Parent is running
Child is running
Cancelling child
Child is cancelled
Parent is not cancelled
Run Code Online (Sandbox Code Playgroud)
如果没有第一个yield,则永远不会打印“ Child is running ”,因为子作业没有机会运行。delay暂停子进程执行并恢复父进程执行。cancel中断delay并将执行移至finally块中。第二join个和第二个yield没有实际效果,但是通过调用join子作业,我们绝对确保只有在子作业完成/取消后才会执行以下任何代码。
经过一番研究,我发现这个术语yield实际上来自计算机科学,而产生线程这个术语是我不理解的。
本质上: yield()基本上意味着线程没有做任何重要的事情,如果其他线程需要运行,它们可以运行。(我更喜欢像 Alex Yu 提到的那样使用 join )。基本上,如果我们想可视化yield正在做什么......你调用 yield 的任何线程都会被推到消息队列的后面,然后其他具有相同优先级的线程在它之前执行。所以这就像去俱乐部的后排。
我对协程也很陌生,我对协程流程的理解是,将launch像上次执行一样执行,就在退出主函数之前。为了确定一些优先级,我们使用 - delay, yield, join。在这个例子中,我们可以改变yield和delay将会得到相同的结果。
流程:
应用程序跳过job = launchgetjob.join()并了解未来的代码正在等待 job = launch' 将完成
应用程序跳过child= launchget 到yield(),或者我们可以使用delay(10)并理解未来的代码并不重要,并且会回到开头,以便child= launch
到达delay(Long.MAX_VALUE)它是一个陷阱
应用程序到达println("Cancelling child")然后到达child.cancel()以及child.join()谁是流程触发器。在这种情况下,我们可以将其替换为yield or join。在此触发器应用程序了解已child = launch取消但未finally执行语句后执行它println("Child is cancelled")。
然后执行yield()(我发现没用)println("Parent is not cancelled")。
你的问题 --- Yield() //为什么我需要这个?????? 因为如果没有,yield应用程序将不会返回到child= launch不会进入try块内,并且当代码到达 child.join() 后,finally withprintln("Child is cancelled")将不会被执行,因为try之前没有触发块。
我建议在调试模式下运行此代码,并在每一行上放置断点,并在 Intellij 中使用“F9”来理解流程,并尝试使用来自 Playground 的 Alex Yu 代码并进行更改delay, yield, join
在您的示例中,yield() 在父作业中被调用。它对你的父母说:“你工作多了,请稍等,我会让其他任务工作一段时间,过一段时间我会让你继续工作”。
因此父作业等待.. 子作业工作一段时间.. 一段时间后,父作业通过 yield() 之后的下一行,并取消子作业。
如果您在示例中不使用 yield(),父作业会立即取消子作业。
让我用不同的例子来解释产量,这些例子以更清晰的方式显示了产量。2 个作业在队列中等待等待线程让它们工作。当您调用 yield 时,线程查看队列并看到其他作业在等待,因此它让其他作业工作。
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.yield
fun main() = runBlocking {
val job1 = launch {
repeat(10) {
delay(1000)
println("$it. step done in job 1 ")
yield()
}
}
val job2 = launch {
repeat(10) {
delay(1000)
println("$it. step done in job 2 ")
yield()
}
}
job1.join()
job2.join()
println("done")
}
Run Code Online (Sandbox Code Playgroud)
输出:
0. step done in job 1
0. step done in job 2
1. step done in job 1
1. step done in job 2
2. step done in job 1
2. step done in job 2
3. step done in job 1
3. step done in job 2
4. step done in job 1
4. step done in job 2
5. step done in job 1
5. step done in job 2
6. step done in job 1
6. step done in job 2
7. step done in job 1
7. step done in job 2
8. step done in job 1
8. step done in job 2
9. step done in job 1
9. step done in job 2
done
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
656 次 |
| 最近记录: |