🔄

スレッドとチャネル — 所有権ベースの並行処理

「メモリを共有して通信するのではなく、通信してメモリを共有せよ」

並行プログラミングで最も怖いのはデータレースだ。2つのスレッドが同じメモリに同時書き込みすると未定義動作が発生する。

Rustではこれがコンパイルエラーだ。&mut Tが1つしか存在できないルールがスレッド境界でも適用される。Send/Syncトレイトが型がスレッド間で安全に移動/共有できるかをコンパイル時に検証。

チャネル(mpsc)

let (tx, rx) = mpsc::channel();
thread::spawn(move || { tx.send(42).unwrap(); });

moveクロージャで所有権をスレッドに移す。送信側はその値をもう使えない。

Mutex

let counter = Arc::new(Mutex::new(0));

Mutexは一度に1スレッドだけがデータにアクセスするようにする。Arcで包んで複数スレッドで共有。

キーポイント

1

std::thread::spawnでOSスレッド生成

2

moveクロージャでデータ所有権をスレッドに移転

3

mpsc::channel()でメッセージパッシング(所有権移動ベース)

4

Arc<Mutex<T>>で共有可変状態を保護

メリット

  • データレースがコンパイルエラー — ランタイム並行性バグを根本から遮断
  • Send/Syncトレイトでスレッド安全性を型で保証

デメリット

  • Mutexデッドロックはコンパイラが検出できない
  • Arc<Mutex>ボイラープレートが他言語より重い

ユースケース

並列データ処理 — Rayonクレートでイテレータを自動並列化 Webサーバー — リクエスト別スレッド+共有状態(DBプール等)

参考資料