チャネル - Rust By Example
Description: Rust by Example (RBE) is a collection of runnable examples that illustrate various Rust concepts and standard libraries.

## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# チャネル

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);
    }