Open5
Rustの排他制御
Rustの排他制御と所有権がよくわからなくなったので書く。
RwLock
Read Write LockはReadはReadのみ、WriteはRead Writeが行えるロックである。
Lock | Read | Write |
---|---|---|
Read Lock | ○ | ☓ |
Write Lock | ○ | ○ |
Read Lockは複数同時獲得できるが、Write Lockは複数同時獲得できない。Rustの参照と可変参照の関係を持つ。Writeの制約が大きいので、書き込みがほとんど起きないときに活用される。
Mutexはクリティカルセクションを行えるプロセスを高々一つに制限するが、RwLockではWrite Lockされていなければいくつでも獲得可能である。
Mutexの獲得について
let lock = Mutex::new(12);
let n= lock.lock().unwrap();
Rustではlockの獲得時にMutexGuardで包む。MutexGuardは保護対象オブジェクトを保護する役割を持つ。Guardはderefトレイトを実装しているので、参照を外すことでオブジェクトへアクセスできる。
let lock = Mutex::new(12);
let n= lock.lock().unwrap();
dbg!(*n+1);//13
Arc
Atomically Reference Counter(Arc)はスレッドセーフな参照カウント型ポインタである。保護対象のオブジェクトを複数のスレッドで共有することを可能にする。参照カウントがアトミックであり、参照カウントによるレースコンディションが起きないようになっている。
以下のような性質を持つ。
- TがSyncマーカトレイトとSendマーカトレイトを実装するなら、Arc<T>はSyncマーカトレイトとSendマーカトレイトを実装する。
つまり、保護対象オブジェクトがSync(複数スレッドから参照されても安全)とSend(他のスレッドに所有権をムーブできる)ならばArcで包まれた保護対象オブジェクトもスレッドセーフです。
Condvar
Condvar(条件変数)はブロックしているスレッドを実行状態に移すどうかを判断する変数のことである。CPUのリソースを節約するためにスレッドをブロックさせている場合に利用する。
基本的には
- ある条件変数Aについてスレッドをwaitさせる。
- 別のスレッドで条件変数Aで待機しているスレッドに通知を送る。
- ある条件変数Aについて待機していたスレッドが実行状態になる。
といった使い方をする。