最終更新日時: 2024年12月21日 11時13分39秒 (JST)
Akira Takahashi が更新

履歴 編集

class template
<mutex>

# std::scoped_lock(C++17)

    namespace std {
      template <class... MutexTypes>
      class scoped_lock;
    }

## 概要

`scoped_lock`は、複数のミューテックスに対するロック取得と解放を、コンストラクタとデストラクタで確実に実行するためのクラスである。

`lock_guard`クラスは単一のミューテックスのみを扱うが、このクラスは複数のミューテックスを一括して管理する。

複数のミューテックスを使用する状況では、ロック取得の順番によってはデッドロックが発生する可能性がある：

    // デッドロックが発生するコード：
    // thread 1
    {
      std::lock_guard<std::mutex> lk1{m1};
      std::lock_guard<std::mutex> lk2{m2};
    }

    // thread 2
    {
      std::lock_guard<std::mutex> lk1{m2}; // ロックの取得順に一貫性がない
      std::lock_guard<std::mutex> lk2{m1};
    }

このような状況では、従来は`std::lock()`関数によってロック取得を行い、ロック取得済みのミューテックスを`std::adopt_lock`戦略でロックの生存期間管理をすることでデッドロックを回避できた。このクラスでは、可変個のミューテックスをデッドロックを回避しながらロック取得と解放を安全に行える。

## メンバ関数

名前 | 説明 | 対応バージョン
--- | --- | ---
`(constructor)` | コンストラクタ | C++17
`(destructor)` | デストラクタ | C++17
`operator=(const scoped_lock&) = delete` | 代入演算子 | C++17

## メンバ型

名前 | 説明 | 対応バージョン
--- | --- | ---
`mutex_type` | ミューテックス型。`MutexTypes...`が単一要素の場合のみ、その別名として定義される | C++17

## 例

    #include <iostream>
    #include <mutex>

    int main()
    {
      std::mutex m1;
      std::timed_mutex m2;

      {
        // m1とm2のロックを取得
        std::scoped_lock lk{m1, m2};

        // m1のミューテックスで保護されたデータと、
        // m2のミューテックスで保護されたデータを操作・・・

      } // lkのデストラクタによって、m1とm2のロックを解放
    }

### 出力

## バージョン

### 言語

- C++17

### 処理系

- Clang: 5.0 ✅
- GCC: 7.3 ✅
- Visual C++: ??

## 関連項目

- `lock_guard`
- C++26 宣言のみで使用しない変数の名前として_をサポート

## 参照

- P0156R2 Variadic `lock_guard` (Rev. 5)
- P0739R0 Some improvements to class template argument deduction integration into the standard library