web-dev-qa-db-ja.com

Kotlin-コルーチンyield()その目的は何ですか?

yield関数の目的が正確にはわかりません。

私が持っているこの例を確認できますか?

私は例 here に従っていますが、とにかく。

これがコードです:

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()

最初の利回りをコメントアウトすると、次の結果が得られます。

  • 子供をキャンセルする

    親はキャンセルされません

しかし、私が収量をそのままにしておくと、次のようになります。

  • 子供をキャンセルする

    子供がキャンセルされました

    親はキャンセルされません

ここでyieldを使用するとはどういう意味ですか?

10
j2emanue

https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/yield.html

現在のコルーチンディスパッチャーのスレッド(またはスレッドプール)を他のコルーチンに譲って実行します。コルーチンディスパッチャーに独自のスレッドプールがない場合(Dispatchers.Unconfinedなど)、この関数は何もせず、コルーチンジョブが完了したかどうかを確認します。この一時停止機能はキャンセル可能です。この中断関数が呼び出されたとき、またはこの関数がディスパッチを待機しているときに、現在のコルーチンのジョブがキャンセルまたは完了した場合、CancellationExceptionで再開します。

それは少なくともいくつかのことを達成します

  1. 現在実行中のCPUタスクの一時的な優先順位を下げ、他のタスクを実行する公平な機会を与えます。
  2. 現在のジョブがキャンセルされているかどうかをチェックします。キャンセルされていない場合、CPUバウンドループで、ジョブは最後までチェックされない可能性があります。
  3. スレッドよりもジョブが多いために競合がある子ジョブの進行を可能にします。これは、現在のジョブが他のジョブの進行状況に基づいて適応する必要がある場合に重要になることがあります。
6
Yuri Schimke

いくつかの調査の後、yieldは実際にはJavaからのものであり、スレッドを生成するという用語は私が理解しなかったものであることがわかりました。

基本的に、yield()は、基本的にスレッドが重要なことを何も実行していないことを意味し、他のスレッドを実行する必要がある場合は実行できます。 (私はアレックス・ユーが述べたように参加を使いたいと思います)。基本的に、yieldが何をしているかを視覚化したい場合は、yieldを呼び出すどのスレッドもメッセージングキューの後ろにプッシュされ、同じ優先度を持つ他のスレッドがその前に実行されます。つまり、クラブで列の最後に行くようなものです。

3
j2emanue