ys memos

Blog

Rustのthread spawnで、変数名を増やさない方法


rust

2024/08/25


Rustでthreadをspawnするとき、変数をmoveすることがあると思います。 その際に、moveすると、変数が移動してしまい、元のスコープで使えなくなります。

ですが、変数名を増やすことなく、元のスコープで使える方法があります。


use std::{sync::Arc, thread};

fn main() {
    let x = Arc::new(10);
    let t1 = thread::spawn(move || {
        println!("[t1] x = {}", x);
    });
    let t2 = thread::spawn(move || {
        println!("[t2] x = {}", x);
    });
    t1.join().expect("Thread panicked");
    t2.join().expect("Thread panicked");
}

これをコンパイルしようとすると、以下のエラーになる。

t2で、すでに移動済みの xを使おうとしているためである。

error[E0382]: use of moved value: `x`
  --> src/main.rs:18:28
   |
4  |     let x = Arc::new(10);
   |         - move occurs because `x` has type `Arc<i32>`, which does not implement the `Copy` trait
...
15 |     let t1 = thread::spawn(move || {
   |                            ------- value moved into closure here
16 |         println!("[t1] x = {}", x);
   |                                 - variable moved due to use in closure
17 |     });
18 |     let t2 = thread::spawn(move || {
   |                            ^^^^^^^ value used here after move
19 |         println!("[t2] x = {}", x);
   |                                 - use occurs due to use in closure


スコープを作って、そこでmoveする。

use std::{sync::Arc, thread};

fn main() {
    let x = Arc::new(10);
    let t1 = thread::spawn({
        let x = x.clone();
        move || {
            println!("[t1] x = {}", x);
        }
    });
    let t2 = thread::spawn({
        let x = x.clone();
        move || {
            println!("[t2] x = {}", x);
        }
    });
    t1.join().expect("Thread panicked");
    t2.join().expect("Thread panicked");
}

thread::scopeを使う。

use std::{sync::Arc, thread};

fn main() {
    let x = Arc::new(10);
    thread::scope(|s| {
        let t1 = s.spawn(|| {
            println!("[t1] x = {}", x);
        });
        let t2 = s.spawn(|| {
            println!("[t2] x = {}", x);
        });
        t1.join().expect("Thread panicked");
        t2.join().expect("Thread panicked");
    });
}


関連タグを探す