Rust で簡易的なマルチスレッドプログラミングをやってみる

2024/07/21に公開

はじめに

Rust にはマルチスレッドプログラミング(並列処理)ができるような仕組みがあります。
所有権という概念も存在するため、それらをうまく管理しつつ、どのように並列処理を実行していくかが気になりますね。
私自身、正直利用回数がまだまだ少なく、半分メモ書きのような形になることをご容赦ください。

std::thread を使う

std::threadモジュールを使うことでスレッドを生成することができるようです。
https://doc.rust-lang.org/std/thread/

生成されたスレッドはメインスレッドから「分離」されるため、
生成されたスレッドがいつ終了するかなどはわからないという特性があります。

use std::thread;

thread::spawn(move || {
    // some work here
});

以下のようなコードを書いいてみました。

use std::thread;

fn main() {
    let mut handles = vec![];

    for i in 0..5 {
        let handle = thread::spawn(move || {
            println!("Hello from thread {}", i);
        });

        handles.push(handle);
    }

    // メインスレッド
    println!("Hello from the main thread");

    // 全てのスレッドの終了を待つ
    for handle in handles {
        handle.join().unwrap();
    }

    // 最後に実行されるメインスレッド
    println!("All threads have finished");
}

for のなかで複数のスレッドを生成し、コンソールに出力する実装を行いました。
複数のスレッドに分かれた処理は、handles に push() し、join() ですべてのスレッドの終了を待って、最後にメインスレッドを実行するという内容です。

これを実行してみると、以下のように出力されました。

Hello from thread 0
Hello from thread 2
Hello from thread 1
Hello from the main thread
Hello from thread 3
Hello from thread 4

マルチスレッドプログラミングの特性上、実行順序が担保されるわけではないということがわかりました。

反対に、マルチスレッドを使わないと以下のようなシンプルなコードになります。
これはメインスレッド内で、繰り返し処理を実行しているので、0~5 のインデックス順に実行がされます。

fn main() {
    for i in 0..5 {
        println!("Hello from thread {}", i);
    }
}

おわりに

Rust を使ったマルチスレッドプログラミングの概念がとてもざっくりですがつかめました。
複数スレッド間で値を共有する ArcMutexという概念もあるようなので、次回以降で触れていきたいと思います。
(所有権 x マルチスレッド x 値の共有は頭がごちゃごちゃになりそうですが。。)

では。

コラボスタイル Developers

Discussion