Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

チャネル、ロック、同期

同期プリミティブのランタイム固有性に関する注記

同期のものを使うのではなく、非同期プリミティブが必要な理由

チャネル

  • 基本的に std のものと同じだが、await する
    • タスク間で通信する(同じスレッドまたは別のスレッド)
  • ワンショット
  • mpsc
  • その他のチャネル
  • 有界チャネルと無界チャネル

ロック

  • 非同期 Mutex
    • 比較: std::Mutex - await ポイントをまたいで保持できる(ガード内で mutex を借用する、ガードは Send、スケジューラ対応? それとも単に lock が async だから?)、lock は async(ロックが利用可能になるのを待つ間スレッドをブロックしない)
      • await をまたいでガードを保持することに対する Clippy lint さえある(https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock)
    • await をまたいで保持できるため、より高コスト
      • 可能なら std::Mutex を使う
        • try_lock を使える、または mutex が競合状態にならないと想定される
    • yield しても lock が魔法のように drop されるわけではない(それこそが lock の要点のようなもの!)
    • await をまたいで mutex を保持することによるデッドロック
      • タスクはデッドロックするが、他のタスクは進行できるため、プロセス統計/ツール/OS ではデッドロックのように見えない可能性がある
      • 通常の助言 - スコープを限定する、ロックを最小化する、ロックの順序を決める、代替手段を優先する
    • mutex poisoning はない
    • lock_owned
    • blocking_lock
      • async では使用できない
    • 他のロックにも当てはまる(上記は mutex を具体的に論じる前に移動すべきか? おそらくそう)
  • RWLock
  • Semaphore
  • yield

その他の同期プリミティブ

  • notify、barrier
  • OnceCell
  • atomics