Rustにおける並行処理入門とシンプルなスレッド例

Rustでは、所有権システムと型チェックにより、多くの並行処理に関するバグがコンパイル時に検出される。この特性は「フェアレス・コンカレンシー(fearless concurrency)」と呼ばれ、開発段階で問題を修正できる点が大きな利点となる。

並行(Concurrent)と並列(Parallel)の違い

並行とは複数のタスクが独立して進行することを指し、必ずしも同時に実行されるわけではない。一方、並列は物理的に同時に実行されることを意味する。ただし、実際の実装では両者が重なり合うことも多い。

Rustの並行処理モデル

  • メッセージパッシング:チャネル(channel)を介してスレッド間でデータを送受信する方式。
  • 共有状態:複数のスレッドが同一のメモリ領域にアクセスする方式。RustではMutexRwLockなどで安全に制御される。
  • SendSync トレイト:これらのトレイトにより、ユーザー定義型も含めてスレッド間での安全なデータ共有が保証される。

シンプルなスレッド使用例

use std::thread;
use std::time::Duration;

fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    let worker = thread::spawn(move || -> Vec<i32> {
        for &n in &numbers {
            println!("Worker thread: {}", n);
            thread::sleep(Duration::from_millis(50));
        }
        numbers
    });

    for i in 0..10 {
        println!("Main thread: {}", i);
        thread::sleep(Duration::from_millis(20));
    }

    let result = worker.join().unwrap();
    println!("Received from worker: {:?}", result);
}

このコードのポイント:

  • move キーワードにより、閉包が所有権を取得し、スレッド間でデータを安全に移動できる。
  • thread::spawnJoinHandle<T> を返し、join() でスレッドの終了を待ち、結果を取得する。
  • スレッド関数のシグネチャは FnOnce() -> T かつ Send + 'static である必要がある。

タグ: rust 並行処理 スレッド 所有権 Send

6月18日 21:37 投稿