迅速な並行処理

3178 ワード

  • 非同期コード-中断して後で再開できます.
  • パラレルコード-コードの複数の部分を同時に実行します.
  • パラレルおよび非同期コードを使用するプログラムは、一度に複数の操作を実行する外部システムを待っている操作を中断し、このコードをメモリセーフに簡単に書くことができます.
  • 非同時並列コードの共通の組み合わせを参照してください.
  • 非同期関数


  • 同期関数とメソッドのいずれかを実行します.
  • 非同期関数またはメソッドはまだこれらの3つのもののうちの1つをします、しかし、それが実行を通過している間、それは中断されることができます.
  • 関数やメソッドが非同期であることを示すには、その宣言にasyncキーワードを書き込みます.
  • 非同期メソッドを呼び出すと、そのメソッドが返されるまで実行を中断します.使用可能なサスペンションポイント
  • をマークするために呼び出しの前で使用を待ってください
    例:
    func listPhotos(inGallery name: String) async -> [String] {
        let result = // some asynchronous networking code
        return result
    }
    
    let photoNames = await listPhotos(inGallery: "Summer Vacation")
    let sortedNames = photoNames.sorted()
    let name = sortedNames[0]
    let photo = await downloadPhoto(named: name)
    show(photo)
    
    プログラムの場所は非同期関数またはメソッドを呼び出すことができます.
  • 非同期関数、メソッド、またはプロパティの本体のコード.
  • コード化された構造、クラス、または列挙体の静的main ()メソッドのコード.
  • 非構造化された子タスクの
  • コード
    上の例では、配列の要素がすべて準備完了後に配列全体を一度に返す代わりに、ループの待機時に使用する非同期シーケンスを使用して一度にコレクションの1つの要素を待機します.
    例:
    import Foundation
    
    let handle = FileHandle.standardInput
    for try await line in handle.bytes.lines {
        print(line)
    }
    
    Waitのループでは、AsyncSequenceプロトコルに準拠する任意の型に対して使用できます.シーケンスの場合も同様です.

    非同期関数の並列呼び出し

  • WAITで非同期関数を呼び出すと、一度に1つのコードだけが実行されます.
  • 非同期関数を呼び出し、その周りのコードと並列に実行させるために、定数を定義するときにletの前に非同期を書き込み、定数を使用するたびに書き込みを待ちます.
  • 例:
    async let firstPhoto = downloadPhoto(named: photoNames[0])
    async let secondPhoto = downloadPhoto(named: photoNames[1])
    async let thirdPhoto = downloadPhoto(named: photoNames[2])
    
    let photos = await [firstPhoto, secondPhoto, thirdPhoto]
    show(photos)
    
  • 次の行のコードがその関数の結果に依存するときに、非同期関数を待機します.これにより順次実行される.
  • あなたのコードの後まで結果を必要としないとき、非同期関数をasyncで呼び出します.これは並行して実行することができる作業を作成します.
  • 構造的並行性


    タスクは、プログラムの一部として非同期で実行できる作業単位です.すべての非同期コードはいくつかのタスクの一部として実行されます.
    タスクは、タスクグループに子として追加することができます.

  • async let構文子タスクを作成します.
  • タスクグループの各タスクは同じ親タスクを持ち、各タスクは子タスクを持つことができます.タスクとタスクグループの間の明示的な関係のため、このアプローチは構造化された並行性
  • と呼ばれています

    非構造化並行性

  • 非構造化タスクは親タスクを持ちません.
  • 現在のアクターで動作する非構造化タスクを作成するには、タスクを呼び出します.init ( priority : operation ):初期化子.
  • 現在のアクターの一部ではなく、より具体的には独立したタスクとして知られている構造化されていないタスクを作成するには、タスクを呼び出します.Address(優先度:操作)クラスメソッド.
  • 俳優

  • 俳優は参照タイプです.
  • クラスとは異なり、
  • では、アクターは1つのタスクだけを一度に変更可能な状態にアクセスすることができます.これは複数のタスクのコードがアクターの同じインスタンスと対話するのを安全にします.
  • あなたは、構造体とクラスと同じ初期化子構文を使用して、俳優のインスタンスを作成します.アクターのプロパティまたはメソッドにアクセスすると、潜在的なサスペンションポイントをマークするのに待機します.
  • 例:
    actor TemperatureLogger {
        let label: String
        var measurements: [Int]
        private(set) var max: Int
    
        init(label: String, measurement: Int) {
            self.label = label
            self.measurements = [measurement]
            self.max = measurement
        }
    }
    
    let logger = TemperatureLogger(label: "Outdoors", measurement: 25)
    print(await logger.max)