RCIE-ジャンクのコード屋

主に自分のためにコーディングのTIPSを蓄積しています。

Rust スレッドに終了命令を送る try_recv

概要

  • スレッドに終了命令を送るには channel を使う。
  • 受信の有無を確認するには try_recv を使う。
  • 受信内容を確認するには match を使う。
プログラム例
  • 本スレッドで1秒待機している間に、別スレッドはカウンタを回す。
  • 本スレッドは別スレッドを停止させて、カウンタを表示する。
use std::sync::mpsc::channel;
use std::thread::{sleep, spawn};
use std::time::Duration;

fn main() {
    let (送信機, 受信機) = channel();
    let 別スレッド = spawn(move || {
        let mut カウンタ = 0 as i64;
        loop {
            match 受信機.try_recv() {
                Ok("停止") => break,
                _ => (),
            }
            カウンタ += 1;
        }
        カウンタ
    });
    sleep(Duration::from_secs(1)); // 1秒停止
    送信機.send("停止").unwrap_or(()); // 停止命令
    let 結果 = 別スレッド.join().unwrap(); // 結果を取り出す
    println!("{}", 結果);
}
結果
  • 1秒間にカウンタを回せる数なので、環境によって差がある。
57502901
解説
fn main() {
    let (送信機, 受信機) = channel();
    let 別スレッド = spawn(move || {
        let mut カウンタ: i64 = 0;
        // └ i32だと桁が足りなくなる可能性を考えてi64にした。
        loop {
            match 受信機.try_recv() {
            // └ 受信していればOk(~)、なければErr(~)が得られる。
                Ok("停止") => break,
                // └ 停止命令を受けたら脱出する。
                _ => (),
                // └ それ以外なら何もしない。
            }
            カウンタ += 1;
        }
        カウンタ
        // └ 別スレッドの結果は「カウンタ」になる。
    });
    sleep(Duration::from_secs(1)); // 1秒停止
    送信機.send("停止").unwrap_or(()); // 停止命令
    let 結果 = 別スレッド.join().unwrap(); // 結果を取り出す
    println!("{}", 結果);
}
補足
  • 既に終了しているスレッドに対して send で送信すると、Err が返ってくるため、unwrap() ではプログラムが停止してしまう。
  • 今回のプログラムは、unwrap() の代わりに unwrap_or(()) を書いて、失敗時にそのまま処理を継続するようにした。