データ競合と競合状態
安全な Rust では、データ競合が存在しないことが保証されています。 データ競合は、以下のように定義されています。
- 2 つ以上のスレッドが並行にメモリ上の場所にアクセスしている
- この内 1 つは書き込み
- この内 1 つは非同期
データ競合は未定義動作を含み、そしてそれ故に安全な Rust で発生させることは不可能です。 データ競合は Rust の所有権システムによってほとんど防がれています。可変参照の エイリアスを生成することは不可能ですから、データ競合を起こすことは不可能です。 内部可変性はこれをもっと複雑にします。これが、 Send トレイトと Sync トレイトが 何故存在するかということの主な理由です (以下を見てください) 。
しかしながら Rust は、一般的な競合状態を防ぎません。
これは根本的に不可能で、そして多分本当に望まれていないものです。ハードウェアは 競合状態を起こし、 OS も競合状態を起こし、コンピュータの他のプログラムも競合状態を起こし、 そして世界中にある全てのプログラムも競合状態を起こします。どんなシステムでも、 全ての競合状態を防げると喧伝しているようなものは、単に間違っているだけではなく、 本当に使いづらいものとなるでしょう。
ですから、安全な Rust のプログラムがデッドロックに陥ったり、正しくない同期によって何か 馬鹿げたことを行なっても、これは全く "問題ない" のです。明らかにそのようなプログラムは、 本当に良くないです。ですが、 Rust は今までのところ、プログラマに我慢してもらうしか出来ないのです。 それでも Rust のプログラムだけでは、競合状態において、メモリ安全性を侵害することは出来ません。 何か他のアンセーフなコードと組み合わせることだけでしか、実際に競合状態において、 メモリ安全性を侵害することが出来ないのです。例: