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 は、スレッド間の通信のために非同期の channels を提供します。チャネルは、 2つのエンドポイント、すなわち SenderReceiver の間で、 情報を一方向に流すことを可能にします。

use std::sync::mpsc::{Sender, Receiver};
use std::sync::mpsc;
use std::thread;

static NTHREADS: i32 = 3;

fn main() {
    // チャネルには2つのエンドポイントがあります: `Sender<T>` と `Receiver<T>`、
    // ここで `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!("スレッド {} が終了しました", id);
        });

        children.push(child);
    }

    // ここで、すべてのメッセージが収集されます
    let mut ids = Vec::with_capacity(NTHREADS as usize);
    for _ in 0..NTHREADS {
        // `recv` メソッドはチャネルからメッセージを取り出します
        // 利用可能なメッセージがない場合、`recv` は現在のスレッドをブロックします
        ids.push(rx.recv());
    }

    // スレッドが残りの作業を完了するのを待ちます
    for child in children {
        child.join().expect("おっと!子スレッドがパニックしました");
    }

    // メッセージが送信された順序を表示します
    println!("{:?}", ids);
}