最終更新日時(UTC): 2025年07月11日 17時16分44秒
Koichi Murase が更新

履歴 編集

class
<mutex>

# std::recursive_mutex(C++11)

    namespace std {
      class recursive_mutex;
    }

## 概要

`recursive_mutex`クラスは、スレッド間で使用する共有リソースを排他制御するためのクラスである。`lock()`メンバ関数によってリソースのロックを取得し、`unlock()`メンバ関数でリソースのロックを手放す。

`mutex`クラスとは異なり、同一スレッドからの再帰的なロック取得を許可する。ミューテックスは内部的に所有権カウントを保持しており、これにより再帰的なロックを管理する。（ここでの所有権カウントは説明用の概念にすぎず、外部から直接観測する事はできない。）

このクラスのデストラクタは自動的に`unlock()`メンバ関数を呼び出すことはないため、通常このクラスのメンバ関数は直接は呼び出さず、`lock_guard`や`unique_lock`といったロック管理クラスと併用する。

## メンバ関数

名前 | 説明 | 対応バージョン
--- | --- | ---
`(constructor)` | コンストラクタ | C++11
`(destructor)` | デストラクタ | C++11
`operator=(const recursive_mutex&) = delete;` | 代入演算子 | C++11
`lock` | ロックを取得する | C++11
`try_lock` | ロックの取得を試みる | C++11
`unlock` | ロックを手放す | C++11
`native_handle` | ミューテックスのハンドルを取得する | C++11

## メンバ型

名前 | 説明 | 対応バージョン
--- | --- | ---
`native_handle_type` | 実装依存のハンドル型 | C++11

## 例

    #include <iostream>
    #include <mutex>
    #include <thread>

    class counter {
      int count_ = 0;
      std::recursive_mutex mtx_;
    public:
      int add(int value)
      {
        std::lock_guard<std::recursive_mutex> lock(mtx_);
        count_ += value;
        return count_;
      }

      int increment()
      {
        std::lock_guard<std::recursive_mutex> lock(mtx_); // ロックを取得する
        return add(1); // add()関数内でも同じミューテックスからロックを取得する
      }
    };

    std::mutex print_mtx_;
    void print_value(int value)
    {
      std::lock_guard<std::mutex> lock(print_mtx_);
      std::cout << "count == " << value << std::endl;
    }

    counter c;
    void change_count()
    {
      int value = c.increment();
      print_value(value);
    }

    int main()
    {
      std::thread t1(change_count);
      std::thread t2(change_count);

      t1.join();
      t2.join();
    }

### 出力

    count == 1
    count == 2

## バージョン

### 言語

- C++11

### 処理系

- Clang: ??
- GCC: 4.7.0 ✅
- ICC: ??
- Visual C++: 2012 ✅, 2013 ✅, 2015 ✅

## 参照