"並行性の設計は、信頼と破壊の境界線上に存在する。"
スレッドという概念は、制御が可能であるかのように語られる。
しかし実際には、**スレッドの間にあるのは“設計されていない自由”と“壊れる可能性”**である。
Rustはこの状況に対して明確に宣言する。
「並行性の安全性は、開発者の注意力ではなく、言語の構文によって保証されなければならない」と。
この章では、スレッドセーフという概念を、Rustがどのように言語の責務として取り込んでいるかを探り、
その哲学的な重さと、構文設計における厳格な意思を読み解いていく。
並行性が“危険”であるという前提
CやC++では、スレッドセーフなコードを記述するのは開発者の責任だった。
それはときに成功するが、多くは破壊的失敗を引き起こす。
- データ競合
- ダングリングポインタ
- ロックの取り忘れ
- デッドロック
このようなヒューマンエラー前提のアーキテクチャを、Rustは拒絶する。
Rustは、「スレッドをまたぐ責任は、型と構文で検証されるべきだ」という哲学に立脚している。
SendとSync:構文によるスレッド安全の境界線
Rustには、以下の二つの自動導出トレイトが存在する。
-
Send
:ある型の値がスレッド間で安全にムーブできること -
Sync
:ある型への参照が複数スレッドから安全に参照できること
この二つによって、Rustは「スレッドをまたいでよいか否か」をコンパイル時に静的に決定する。
例:
fn spawn_thread(data: Arc<Mutex<T>>) where T: Send + Sync {
std::thread::spawn(move || {
// 安全にデータにアクセス
});
}
これは、「型がスレッドにまたがることを許すだけの構造的保証を持っている」という宣言である。
非Send型の存在は“設計の拒否”である
let not_send = Rc::new("hello");
std::thread::spawn(move || {
println!("{}", not_send); // コンパイルエラー
});
このエラーは、「Rc<T>
はスレッドをまたげない」という型設計に基づく。
つまり、この値は“そう使うべきではない”という設計哲学が、構文レベルで防衛線を張っている。
開発者が考えるより先に、言語が先回りして設計の逸脱を拒絶する。
これがRustの「言語による責務」の思想である。
スレッドセーフは「意識するもの」から「構文で定義するもの」へ
C++やJavaでは、並行性の正しさは「誰かがレビューで気づく」ことで守られていた。
Rustでは、それを構文によって未然に封じ込める。
- スレッドをまたぐ値には
Send
が要求される - クロージャーにキャプチャされた参照には
Sync
が必要 -
Arc<T>
はT: Send + Sync
でなければならない
このように、並行性を扱うすべての操作は、型システムと構文ルールによって強制的に安全へと導かれる。
スレッド安全の構文とは、意識の省略ではない。意図の構造化である
Rustでは「スレッドセーフだから考えなくてよい」のではない。
むしろ、考えるべきことを型に閉じ込めておくという設計手法なのだ。
fn safe_parallel<T: Send + 'static>(f: T) {
std::thread::spawn(move || {
// ...
});
}
この関数は、「T
は安全に送られるべき型である」という制約を型パラメータで明示している。
これは、スレッドセーフという設計条件をコンパイラと契約する構文である。
unsafeな並行性へのアクセスは“宣言された危険”である
Rustには unsafe
という逃げ道がある。
しかし unsafe
を書くということは、**「私はここで安全の保証を放棄し、責任を引き受ける」**という明示的宣言である。
例:
unsafe {
static mut SHARED: i32 = 0;
SHARED += 1;
}
このコードは、“設計の外”で書かれたものであることを、構文で明らかにしている。
Rustは、構文によって開発者と設計の倫理契約を交わしているのだ。
並行性を“使わせない設計”が安全性を生む
Rustの型システムは、**「やってはいけないことを簡単にできない」**という美学に基づいている。
これは並行性において最も顕著であり、構文によって並行設計の秩序を守ることを言語の責務としている。
- 使えないものは使えない(非Sync, 非Send)
- 書けるがunsafeを要求するものは警告される
- コンパイル時にすべてが検査される
この「設計として不可能なことを不可能とする構文設計」こそが、Rust最大の革新である。
結語:安全は自由ではない。構文が制限し、設計が導く
スレッドセーフなコードを書くことは、自由ではない。
Rustではそれは構文と型システムによって設計的に導かれる、ある種の強制である。
だがこの強制こそが、人の注意力に依存しない安全を生み出し、
同時性という不確定性に設計という秩序を持ち込むための、言語としての覚悟なのである。
"並行性の信頼は、設計に任せてはならない。言語がそれを構文として管理すべき時代に、Rustは生まれた。"