[Kotlin]Coルーチンについて


今日はコルディン(以下、コルディンと略称する)についてお話しします.
これは多くのアプリケーションで、コルディンを利用してサービス団を開発し、行う際に学ばなければならない機能です!そう思うよ今はまだあまり得意ではありませんが、コンセプト的な部分を埋めたいと思います!
そして、グルディンの量は私が想像していたより膨大だと思います.kotlinがcoluceneを提供しているだけでなく、多くの言語が提供しているので、その概念をもっと詳しく理解しましょう.
まず、木の上のコルディンの定義を見てみましょう.

Coルーチンの定義

코루틴は、サブルーチンを一時停止および復元することができるコンポーネントを指す.
簡単に言えば、必要に応じて一時停止できる関数です.
coluceneは一時停止とリカバリが可能な関数を表します!Javascriptを知っている人は、非同期をサポートする機能がcoroutineであることをすぐに感じることができます.
では、正義をもっと詳しく説明しましょう.
≪サブルーチン|SubProgram|emdw≫:複数のコマンドに名前を付け、繰り返し呼び出し可能なプログラムを定義します.
そしてサブプログラムは함수と理解できる!서브루틴として定義された関数は、繰り返し呼び出し可能な関数と命名することができる.
うん.では、方法も関数もサブルーチンではないでしょうか.
はい.サブルーチンが正しい
しかし、コルディンが言うサブプログラムが持つ色はやや異なる.複数の関数を定義して使用すると,関数間が相互に協力しているとは感じにくい.ここで、협력は、PCまたはモバイルデバイス上の限られたリソースが関数によって使用されることを意味する.
あなたはこのような考えを持っています.
threadは資源を交換する過程で、臨界領域によって予想外の問題が発生したのではないでしょうか.
しかし、コルティンには問題は起こらない.
理由をみんなに伝えよう

なぜCo定例非同期問題が発生しないのですか?


  • サブルーチン(関数、メソッド)にアクセスできる方法は1つだけで、毎回アクティブ化レコードがスタックに割り当てられ、サブルーチン内部のローカル変数などが初期化されます.

  • サブルーチンではreturnを複数回使用でき、サブルーチンの停止運転を制御することで、制御を要求するサブルーチンにリソースを返すことができます.制御を要求するサブルーチンは、複数のリソースを受信することができる.

  • このプロセスで、前のサブルーチンに戻ると、アクティブ化レコードはスタックから消えます.これにより、すべての実行ステータスが失われます.

  • このサブルーチンを複数回繰り返すと、常に同じ結果が得られます.
  • もちろん、少し注意が必要です.전역 변수나 다른 부수 효과는 없어야된다.は仮定を必要とする.
    また、コルディンのもう一つの特徴は非占有である.これは、オペレーティングシステムがサブルーチンを強制的に停止し、他のサブルーチンを実行できないことを意味します.したがって,各サブプログラムが互いにアクティブに協力してこそ,サブプログラムを正常に動作させることができる.
    画像のソース

    各インスタンスが実行された後に再起動するのが表示されます.
    最終的に、Kotlinのルーチンはmainのmainルーチンとcoroutineです.これは、単独で実行可能な操作ルーチンが、開発者が実行および終了を制御する単位をcoroutineと呼ぶことができることを意味する.
    これらのCoルーチンを実行するもう一つの領域はThreadである.

    Coルーチンの役割


    個人的には,Coルーチンの学習において最も重要な概念は一時停止であると考える.何が途切れるの?これが関数です.関数Aの実行時に停止し、関数Bの実行時に関数Aに戻り操作を続行します.主にJavaScriptを使っている人なら非同期?そう思うよはい、Coルーチンは非同期処理のためのライブラリです.もちろんです.
    もっと具体的な例を挙げてみましょう.

  • Main Thread→タスク1を実行する場合、タスク3の結果Aが必要となります.

  • IO Thread→タスク1および他のThreadはタスク3を行い、結果Aを得るために演算を行っている.

  • 結果Aが得られると、メインThread→タスク1が停止し、メインThreadは別の操作2を実行する.

  • Main Thread→タスク2を完了します.

  • IO Thread→タスク3で結果Aをタスク1に渡す.

  • Main Thread→タスク1を復元.
  • Jobと呼ばれています.
    では、これらのCoルーチンの機能をどのように使うのでしょうか.いろいろな場所で使われています特にBackground Taskが必要な場合は、このCoroutineを使用してネットワーク、データベースにアクセスすることがよくあります.
    では、Retrofit、OkHttp 3、UrlconnectionまたはRoom、SQLiteのいずれもCoルーチンを使用することができる.

    より詳細なKotlin Coルーチン概念


    coroutineを使用する場合はimport kotlinx.coroutine.*をインポートする必要があります.これは、すべてインポートする必要があることを意味します.
    import kotlinx.coroutines.* // Coroutine 사용 파일 최상단에 import 해야 합니다.
    Coroutineは、coroutineのScopeと呼ばれる制御範囲と実行範囲を指定することによって制御される.これはglobal scopeとcoroutine scopeもサポートします.
  • global scope:プログラム内の任意の位置で制御可能、アクティブ範囲
  • Coroutine scope:特定の目的のDispatcherを指定することで、制御および操作可能な範囲
  • そうなるとそういう考えがある
    Dispatcherって何?
    Dispatchの翻訳は보내다を意味します.何が出るの?まだ何を送るか分からないけど、작업을 위한 코드를 coroutine scope로 보낸다!という意味です
    一般的な意味でのDispatchは、
    マルチプログラミングシステムで、選択して実行
    ものつまり、キュー内で待機しているプロセスを中央プロセッサとして選択する
    付与された権限のアクション.
    もちろん、上記のDispatchの意味は状況によって異なる場合があります.
    基本的な概念について理解しました
    Coルーチンを用いる場合,Job処理のScopeはグローバルScopeまたはCoルーチンScopeに分けられる.
    Dispatcherは、以下の方法で詳細に区別できます.
  • Dispatchers.Default:基本的なバックグラウンド操作を制御する
  • Dispatchers.IO:I/Oに対して最適化された
  • 操作
  • Dispatchers.main:mainthreadでの動作
  • 注意:上記のDispatcher制御は、すべてのプラットフォームでサポートされていません.
    まず開発者にどのDispatcherで処理するかを教えるべきでしょう.これは、まずscopeを作成する必要があることを意味します.
    val scope = CorouineScope(Dispatcher.Default)
    val coroutineA = scope.launch {}
    val coroutineB = scope.async {}

    launch 🆚 async


    Launchおよびasyncはkotlin cooutineの代表的なブロックである.
    この2つの違いは、値を返すのは何ですか?.
  • launch:戻り値はJobオブジェクト
  • async:戻り値がDeferedオブジェクト
  • もっと気になる友達JobDefferedの具体的な違いは何ですか?そう思える
    この2つのオブジェクトは、scopeごとに返されるオブジェクトを表します.書き込みlaunch lambdaはJobオブジェクトを返し、書き込みasync lambdaはDeferedオブジェクトを返します.
    以下に両者を構成する実際のコードを示す.
    // launch
    public fun CoroutineScope.launch(
        context: CoroutineContext = EmptyCoroutineContext,
        start: CoroutineStart = CoroutineStart.DEFAULT,
        block: suspend CoroutineScope.() -> Unit
    ): Job  {
        val newContext = newCoroutineContext(context)
        
        val coroutine = if (start.isLazy) {
            LazyStandaloneCoroutine(newContext, block)
        } else {
            StandaloneCoroutine(newContext, active = true) // 여기!
        }
        
        coroutine.start(start, coroutine, block)
        return coroutine
    }
    
    //async
    public fun <T> CoroutineScope.async(
        context: CoroutineContext = EmptyCoroutineContext,
        start: CoroutineStart = CoroutineStart.DEFAULT,
        block: suspend CoroutineScope. () -> T
    ): Deferred<T> {
        val newContext = newCoroutineContext(context)
        
        val coroutine = if (start.isLazy) {
            LazyDeferredCoroutine(newContext, block)
        } else {
            DeferredCoroutine<T>(newContext, active = true) // 여기!
        }
        
        coroutine.start(start, coroutine, block)
        return coroutine
    }
    launchのStandaloneCoroutineとasyncのDeferredCoroutine<T>と関数の出力値を除いて、他の違いはないことがわかります.
    正直まだ感じてないでしょ?コードには、両者の概念的な違いが正確に指摘されていない可能性があります.
    そう思うよJobは、その名の通りCoroutineのすべてのタスクです.場合によっては、Jobに戻り値がない場合があります.または、Jobは、未完了のすべてのタスクを含む.関数の因子block 타입を見てください.
    高次関数の形で入ったところ!
    Launchの場合、CoroutineScope()はUnit(戻り値なし)
    Deferredの場合、CoroutineScope()はT(ジェニーリック)です.
    このような違いがある
    より詳細には、Deferredは연기하다である.何を演じますか.それが受信結果値です.いつになるかはわかりませんが、結果値は将来の特定の時点で現れることは間違いありません.
    これはDeferred Jobの拡張インタフェースです.Deferredのコードを開くとこうなります
    public interface Deferred<T: out> : Job {
    	public suspend fun await(): T
        public val onAwait: SelectClause1<T>
    }
    上記のコードは、Deferred interfaceがJobを継承していることを示しています.Deferedはジョブとみなされるため、ジョブのすべてのプロパティが取得されます.
    Launchと各コードの使用方法については、後で追加します.