ハイサイ!オースティンやいびーん。

問題

Rustのstd::sync::mpsc::ChannelのReceiverを別のスレッドに移動させて、iterしていると、そのスレッドのハンドルに足してjoinを呼んでも永遠に解決しない。

    let (tx, rx) = mpsc::channel();

    let handle = thread::spawn(move || -> Result<(), mysql::Error> {
        for data in rx.iter() {
            ///
        }

        Ok(())
    });

解決法その1

Transmitter(配信体)を無理やりdropして解放する:

    let (tx, rx) = mpsc::channel();

    let handle = thread::spawn(move || -> Result<(), mysql::Error> {
        for data in rx.iter() {
            ///
        }

        Ok(())
    });

/// ...

drop(tx);

handle.join().unwrap(); // OK!

最も簡単です。ただ多分何かと間違っているのでしょう これが一番明示的でいいでしょう! @namn1125 ありがとうございます。

enumを使って、完了のメッセージを配信する

より優雅な解決法でしょう。

enum Message {
    Add(u64),
    Finished,
}

let (tx, rx) = mpsc::channel();

let handle = thread::spawn(move || -> Result<(), mysql::Error> {
    for data in rx.iter() {
        match data {
            Message::Add(n) => {},
            Message::Finished => {
                break;
            },
    }

    Ok(())
});

tx.send(Message::Finished);

handle.join().unwrap(); // OK!

しかしやや冗長です。

まとめ

以上、Rustで別スレッドに移動したmpscの受信体のiterを止めて、綺麗にスレッドを終了させる方法を紹介しました。

特に感想はないのですが、読者さんには僕よりずっとRust経験が豊富な方がたくさんいると思いますので、ぜひコメントで技を共有していただけると嬉しいです。

bannerAds