Module std::thread の::spawn
を使うことで新しいスレッドを作ることができます。::span
には関数を渡しその関数の戻り値T
をラップしたJoinHandle<T>
を返します。
以下は例です。スレッドはJoinHandle::join
を使わなければスレッドの完了を待ってくれないのでhello from a thread
と表示されずに終了してしまいます。
use std::thread;
let handler = thread::spawn(|| {
println!("hello from a thread");
// `::join`で待ってるのでちゃんとターミナルなどに表示される
});
let thirty_three = handler.join().unwrap();
関数の戻り値はjoin().unwrap()
で受け取れます。
use std::thread;
let handler = thread::spawn(|| {
33
});
let thirty_three = handler.join().unwrap();
assert_eq!(thirty_three, 33);
Function std::sync::mpsc::channel を使った方法でも値の送受信ができます。
上記の方法のようにJooinHandle::join
だけでなく以下のreceiiver.recv
を使う方法でもスレッド処理を待つことができます。
use std::sync::mpsc::channel;
use std::thread;
let (sender, receiver) = channel();
thread::spawn(move || {
sender.send(33).unwrap();
});
println!("{}", receiver.recv().unwrap())
送信した値は、FIFO で受信できます。また、注意として送信する値はSend
を持ってる必要があります。
以下は、
i=0
の時は2秒待つi=1
の時は1秒待つi=2
の時は待たない
で合計3回送信する例です。
スレッドでメインスレッドよりもVec
の各u64
が長生きしてしまう可能性や、sender
は所有権を渡す必要からいくらか::clone
してます。
これは1秒毎に2
、1
、0
と表示されプログラムが終了します。
use std::sync::mpsc::channel;
use std::sync::Arc;
use std::thread;
use std::time::Duration;
let (sender, receiver) = channel();
let secs = vec![Arc::new(2_u64), Arc::new(1_u64), Arc::new(0_u64)];
{
for (i, sec) in secs.iter().enumerate() {
let sender = sender.clone();
let sec = sec.clone();
thread::spawn(move || {
thread::sleep(Duration::from_secs(*sec));
sender.send(i).unwrap();
});
}
for _ in 0..secs.len() {
println!("{:?}", receiver.recv().unwrap());
}
}
受信でもfor
構文を使っているのは、FIFO なので受信側も送信側と同じ回数繰り返し実行しなければすべて取り出せないからです。例えばこの部分を、
// for _ in 0..secs.len() {
println!("{:?}", receiver.recv().unwrap());
// }
だけにすると、2
だけが表示されプログラムが終了します。