目次

Rustの勉強[並行性 その4]

ぎじゅつ

はじめに

#

NO IMAGEThe Rust Programming Language 日本語版 - The Rust Programming Language 日本語版
を読んでいる

お勉強

#

NO IMAGEメッセージ受け渡しを使ってスレッド間でデータを転送する - The Rust Programming Language 日本語版

  • ここから
  • 今日の電車が終わってるほどうるさいので完全集中する

メモ

#
use std::sync::mpsc;
use std::thread;
use std::time::Duration;

fn main() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        // スレッドからやあ (hi from the thread)
        let vals = vec![
            String::from("hi"),
            String::from("from"),
            String::from("the"),
            String::from("thread"),
        ];

        for val in vals {
            tx.send(val).unwrap();
            thread::sleep(Duration::from_secs(1));
        }
    });

    for received in rx {
        println!("Got: {}", received);
    }
}
  • なるほどね
  • これVecをそのまま送れないんだろうか
    • まあいいか

メインスレッドにおいて、最早recv関数を明示的に呼んではいません: 代わりに、 rxをイテレータとして扱っています。受信した値それぞれを出力します。 チャンネルが閉じられると、繰り返しも終わります。

  • ほんとだ
  • rxをイテレータとして扱えるということはnextトレイトが実装してあるはず

mpscは、mutiple producer, single consumerの頭字語であると前述しました。

  • oh、読み飛ばしてた
// --snip--

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

    let tx1 = tx.clone();
    thread::spawn(move || {
        let vals = vec![
            String::from("hi"),
            String::from("from"),
            String::from("the"),
            String::from("thread"),
        ];

        for val in vals {
            tx1.send(val).unwrap();
            thread::sleep(Duration::from_secs(1));
        }
    });

    thread::spawn(move || {
        // 君のためにもっとメッセージを (more messages for you)
        let vals = vec![
            String::from("more"),
            String::from("messages"),
            String::from("for"),
            String::from("you"),
        ];

        for val in vals {
            tx.send(val).unwrap();
            thread::sleep(Duration::from_secs(1));
        }
    });

    for received in rx {
        println!("Got: {}", received);
    }

    // --snip--
  • なるほどね
  • この命名規則にするならtx1tx2にしてほしかった
  • 特に言うことはない

システム次第で、別の順番で値が出る可能性もあります。並行性が面白いと同時に難しい部分でもあります。

  • まぁそりゃそうだよな

NO IMAGE状態共有並行性 - The Rust Programming Language 日本語版

  • 漢字いっぱいでてきた

状態共有並行性

  • urlがshared stateになってるからこっちのがわかりやすいだろ
  • 日本語ムズすぎ
  • 光らせとくか
  • でたー!Mutex<T>
    • なるほど
    • 多分Mutexでstateを共有するって話だな
    • 並列で全部完了したらとか値が揃ったら次みたいな処理が書けそう

NO IMAGE状態共有並行性 - The Rust Programming Language 日本語版

  • あとここ無限に書いてある
  • 読むか

複数の所有権は複雑度を増させます

  • それはそう
  • なんかこれってstatelessにシステムを構築したらいらなさそうなんだよな
    • ちょっとした処理とか
    • そのバイナリ内で完結したい場合ぐらいしかなさそう

mutual exclusion(相互排他)の省略形です

  • なるほど
  • 余談だが音質をPCで限界まで良くしようとした時に排他処理という話が無限に出てきて混乱したな
    • wasapiとかasioとか

ミューテックスはロックシステム経由で保持しているデータを死守する(guarding)と解説されます。

  • お、DBの排他制御みたい
    • 更新するときにversionみたいなカラムを取得しといてupdateのwhereに含めるやつ

ミューテックスは、2つの規則を覚えておく必要があるため、難しいという評判があります:

データを使用する前にロックの獲得を試みなければならない。
ミューテックスが死守しているデータの使用が終わったら、他のスレッドがロックを獲得できるように、 データをアンロックしなければならない。

  • んー?
    • 論理的には全く難しくないな

まとめ

#
  • 想像しうる内容だった
  • どちらかと言えばメッセージとMutexの使い分けのほうが気になるかもしれない
    • どちらも構造体は持てそうだし
  • オブシディアンの自動補完がゴミなので早くメモアプリ作りたい
  • 次はこれ

NO IMAGE状態共有並行性 - The Rust Programming Language 日本語版