Open2

rust / Mutex Rwlock

katayama8000katayama8000

Mutex

  • ref
  • 語源
    • Mutual Exclusion
    • 相互排除
  • スマートポインタ
  • 排他制御を行う
    • 排他制御(Exclusive Control)は、複数のプロセスやスレッドが同時に共有リソースにアクセスすることを制限するための概念です。共有リソースへの同時アクセスが発生すると、競合状態(Race Condition)が生じ、予期しない結果やデータの破損が発生する可能性があります。そのため、排他制御は共有リソースの整合性を保ち、競合状態を防ぐための手法や機構です。

サンプルコード

スレッド間で所有権を共有するため、Arcを使う

use std::sync::{Arc, Mutex};
use std::thread;

pub fn run() {
    // 共有される可変なデータを保持するMutexを作成します。
    let counter = Arc::new(Mutex::new(0));

    let mut handles = vec![];

    for _ in 0..10 {
        // スレッドごとにMutexのクローンを作成し、Arcで共有します。
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            // Mutexのロックを取得し、共有データにアクセスします。
            let mut num = counter.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    // すべてのスレッドの実行が終了するまで待機します。
    for handle in handles {
        handle.join().unwrap();
    }

    println!("Result: {}", *counter.lock().unwrap());
}

この例では、10個のスレッドが同時に実行され、それぞれが共有されたcounter変数をインクリメントしようとします。しかし、Mutexが使われているため、複数のスレッドが同時にカウンターを更新することはありません。Mutexは、排他的なアクセスを保証します。

katayama8000katayama8000

Mutex RwLock の違い

利用の目的

Mutex(ミューテックス): ミューテックスは、共有リソースへの排他的アクセスを実現するために使用されます。一度に1つのスレッドしかリソースにアクセスできないようにします。
RW Lock(リードライトロック): RW Lockは、リソースへの読み取りアクセスと書き込みアクセスの両方を管理します。読み取りアクセスは同時に複数のスレッドで行うことができますが、書き込みアクセスは排他的であり、他のスレッドの読み取りおよび書き込みをブロックします。

アクセスのタイプ

Mutex: ミューテックスは排他的なアクセスを提供します。つまり、あるスレッドがミューテックスを所有しているときに他のスレッドはそのリソースにアクセスできません。
RW Lock: RW Lockは読み取りアクセスと書き込みアクセスを区別します。読み取りアクセスは共有され、同時に複数のスレッドで行うことができますが、書き込みアクセスは排他的です。

性能

Mutex: ミューテックスはシンプルな排他制御メカニズムであり、ロックを獲得するときにほとんどの場合、他のスレッドによるブロックが発生します。
RW Lock: RW Lockは、読み取りアクセスが多く書き込みアクセスが比較的少ない場合に優れた性能を発揮します。なぜなら、読み取りアクセスは共有され、同時に複数のスレッドで行えるためです。ただし、書き込みアクセスが頻繁に発生する場合は、RW Lockのオーバーヘッドが大きくなる可能性があります。

デッドロックのリスク

Mutex: ミューテックスの間でデッドロックが発生する可能性があります。たとえば、スレッドAがミューテックス1をロックし、スレッドBがミューテックス2をロックしようとするが、同時にスレッドBがミューテックス1を待っている場合などです。
RW Lock: RW Lockでは、読み取りロックと書き込みロックが別々のロックであるため、デッドロックのリスクが低くなります。