チャネル
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); }