【Rust】マルチスレッド

thread::spawn関数で新規スレッドを生成する。

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

fn main(){
    let th = thread::spawn (|| {
        for _i in 1..10 {
            println!("A");
            thread::sleep(Duration::from_millis(500));
        }
    });
    th.join().unwrap();
    println!("Finished");
}

スレッドからスレッド外変数を参照するにはmoveを使用する。

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

fn main(){
    let str = String::from("ABC");
    let th = thread::spawn (move|| {
        for _i in 1..10 {
            println!("{}", str);
            thread::sleep(Duration::from_millis(100));
        }
    });
    th.join().unwrap();
    println!("Finished");
}

C/C++ で新しいスレッドを立ち上げる

#include <thread>
#include <cstdio>
#include <cstdint>

uint32_t end_flag_;
uint32_t msg_;

void ThreadA()
{
    int32_t input = 0;
    while(end_flag_){
        printf("数字を入力してください\n");
        printf("0...スレッドBにメッセージを送信します\n");
        printf("1...プロセスを終了します\n");
        scanf("%d", &input);

        switch(input){
            case 0:
                msg_ = 1;
                break;
            case 1:
                end_flag_ = 0;
                break;
            default:
                printf("0か1を入力してください。\n");
                break;
        }
    }
    printf("スレッドA終了\n");
}

void ThreadB()
{
    while(end_flag_){
        if(msg_){
            printf("スレッドAからメッセージを受信しました\n");
            msg_ = 0;
        }
    }
    printf("スレッドB終了\n");
}

int main() {
    msg_ = 0;
    end_flag_ = 1;

    std::thread th_a(ThreadA);
    std::thread th_b(ThreadB);

    th_a.join();
    th_b.join();

    return 0;
}

Rustで書いてみる

use std::thread;

fn main(){
    let mut msg_ : u32 = 0;
    let mut end_flag_ : u32 = 1;

    let thA = thread::spawn (move|| {
        while end_flag_ != 0 {
            println!("数字を入力してください");
            println!("1...スレッドBにメッセージを送信します");
            println!("2...プロセスを終了します");
            let mut word = String::new();
            std::io::stdin().read_line(&mut word).ok();
            let num: i32 = word.trim().parse().ok().unwrap();
            println!("入力値: {}", num);
            match num {
                1 => { msg_ = 1}
                2 => { end_flag_ = 0}
                _ => println!("0か1を入力してください"),
            }
        }
    });

    let thB = thread::spawn (move|| {
        while end_flag_ != 0 {
            if msg_ == 1 {
                println!("スレッドAからメッセージを受信しました。");
                msg_ = 0;
            }
        }
    });
    thA.join().unwrap();
    thB.join().unwrap();
}

スレッドは二つ立っているんだけど、moveで所有権が移転すると、変数msg_がもう読み込まれなくなる。なるほど、難しいね。