チャネル
Rustは、スレッド間のコミュニケーションのために、非同期のチャネルを提供しています。チャネルは2つのエンドポイント、すなわち送信者と受信者を介して、情報の一方向への流れを作り出すことを可能にしています。
use std::sync::mpsc::{Sender, Receiver};
use std::sync::mpsc;
use std::thread;
static NTHREADS: i32 = 3;
fn main() {
// チャネルには`Sender<T>`と`Receiver<T>`という2つのエンドポイントがあります。
// ここで、`T`は送信されるメッセージの型です。
// (型アノテーションは必須ではありません。)
let (tx, rx): (Sender<i32>, Receiver<i32>) = mpsc::channel();
let mut children = Vec::new();
for id in 0..NTHREADS {
// 送信者エンドポイントはコピーすることができます。
let thread_tx = tx.clone();
// ここでは、それぞれのスレッドが自身のIDを送信しています。
let child = thread::spawn(move || {
// スレッドは`thread_tx`の所有権をとり、それぞれのスレッドは
// メッセージをチャネルにキューイングします。
thread_tx.send(id).unwrap();
// 送信はノンブロッキングなオペレーションなので、
// メッセージを送信した後もすぐに実行を継続します。
println!("thread {} finished", id);
});
children.push(child);
}
// ここで、全てのメッセージが収集されます。
let mut ids = Vec::with_capacity(NTHREADS as usize);
for _ in 0..NTHREADS {
// `recv`メソッドはチャネルからメッセージを取り出します。
// もし取り出せるメッセージが存在しない場合、`recv`は
// 現在のスレッドをブロックします。
ids.push(rx.recv());
}
// Wait for the threads to complete any remaining work
for child in children {
child.join().expect("oops! the child thread panicked");
}
// メッセージが送信された順番を表示。
println!("{:?}", ids);
}