6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Rustでmpscチャンネルの受信スレッドを綺麗に止める方法

Last updated at Posted at 2023-08-29

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

問題

Rustのstd::sync::mpsc::ChannelReceiverを別のスレッドに移動させて、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!

最も簡単です。ただ多分何かと間違っているのでしょう これが一番明示的でいいでしょう!:joy: @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経験が豊富な方がたくさんいると思いますので、ぜひコメントで技を共有していただけると嬉しいです。:relaxed:

6
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?