Send と Sync による拡張可能な並行性

Beginner

This tutorial is from open-source community. Access the source code

はじめに

Send と Sync トレイトによる拡張可能な並行性へようこそ。この実験は、Rust ブックの一部です。LabEx で Rust のスキルを練習することができます。

この実験では、Rust の 2 つの並行性の概念である SendSync トレイトを調べます。これらは、標準ライブラリを超えた拡張可能な並行性機能を提供します。

Send と Sync トレイトによる拡張可能な並行性

興味深いことに、Rust 言語には並行性機能が非常に少ない。この章でこれまで話してきたほとんどの並行性機能は、標準ライブラリの一部であり、言語自体には含まれていない。並行性を扱うためのオプションは、言語や標準ライブラリに限定されない。独自に並行性機能を書いたり、他人が書いたものを使ったりすることができる。

ただし、言語には 2 つの並行性概念が組み込まれている。std::marker トレイトである SendSync である。

Send を使用したスレッド間の所有権の譲渡

Send マーカートレイトは、Send を実装する型の値の所有権がスレッド間で譲渡可能であることを示します。ほとんどすべての Rust 型は Send ですが、Rc<T> を含むいくつかの例外があります。これは Send にできません。なぜなら、Rc<T> の値をクローンし、そのクローンの所有権を別のスレッドに譲渡しようとすると、両方のスレッドが同時に参照カウントを更新する可能性があるからです。このため、Rc<T> は、スレッドセーフなパフォーマンスペナルティを支払いたくないシングルスレッドの状況で使用するために実装されています。

したがって、Rust の型システムとトレイト境界は、Rc<T> の値を誤ってスレッド間で安全でない方法で送信することが決してないように保証します。リスト 16-14 でこれを行おうとしたとき、エラー the trait Send is not implemented for Rc<Mutex<i32>> が発生しました。Send である Arc<T> に切り替えたとき、コードはコンパイルされました。

完全に Send 型で構成される型は、自動的に Send としてマークされます。生のポインタ(第 19 章で説明します)を除き、ほとんどすべてのプリミティブ型は Send です。

Sync による複数のスレッドからのアクセスの許可

Sync マーカートレイトは、Sync を実装する型が複数のスレッドから参照されることが安全であることを示します。言い換えると、型 T&TT への不変参照)が Send である場合、つまり参照が安全に別のスレッドに送信できる場合、Sync です。Send と同様に、プリミティブ型は Sync であり、完全に Sync である型で構成される型も Sync です。

スマートポインタ Rc<T> も、Send でない理由と同じ理由で Sync ではありません。RefCell<T> 型(第 15 章で説明しました)と関連する Cell<T> 型のファミリは Sync ではありません。RefCell<T> が実行時に行う借用チェックの実装はスレッドセーフではありません。スマートポインタ Mutex<T>Sync であり、「複数のスレッド間で Mutex<T> を共有する」で見たように、複数のスレッドでのアクセスを共有するために使用できます。

Send と Sync を手動で実装するのは非安全です

SendSync トレイトで構成される型は、自動的に Send および Sync でもあるため、これらのトレイトを手動で実装する必要はありません。マーカートレイトとして、それらには実装するメソッドさえありません。それらは、並行性に関連する不変条件を強制するのに役立つだけです。

これらのトレイトを手動で実装するには、非安全な Rust コードを実装する必要があります。第 19 章で非安全な Rust コードの使用について説明します。今のところ、重要な情報は、Send および Sync の部分で構成されていない新しい並行型を構築するには、安全保証を維持するために慎重な考えが必要であるということです。https://doc.rust-lang.org/stable/nomicon の「Rustonomicon」には、これらの保証とそれらを維持する方法に関する詳細な情報があります。

まとめ

おめでとうございます!Send と Sync トレイトによる拡張可能な並行性の実験を完了しました。さらにスキルを向上させるために、LabEx でさらに多くの実験を行ってみてください。