scoped_lock クラスは、構築時に 1 つ以上のミューテックスを取得し、破棄時にそれらを解放します。 複数のミューテックスが指定されている場合、デッドロック回避アルゴリズム ( std::lockと同等) が使用され、デッドロックが回避されます。 C++17 で導入されました。
構文
// Single mutex type version
template <class _Mutex>
class _NODISCARD_LOCK scoped_lock<_Mutex> {
public:
using mutex_type = _Mutex;
explicit scoped_lock(_Mutex& _Mtx) : _MyMutex(_Mtx) { // construct and lock
_MyMutex.lock();
}
explicit scoped_lock(adopt_lock_t, _Mutex& _Mtx) noexcept
: _MyMutex(_Mtx) {} // construct but don't lock
~scoped_lock() noexcept {
_MyMutex.unlock();
}
scoped_lock(const scoped_lock&) = delete; // prevent creating a new scoped_lock by copying an existing one
scoped_lock& operator=(const scoped_lock&) = delete; // prevent assigning one scoped_lock to another
};
// multiple mutex types version
template <class... MutexTypes>
class scoped_lock {
explicit scoped_lock(MutexTypes&... m);
explicit scoped_lock(MutexTypes&... m, adopt_lock_t);
~scoped_lock();
scoped_lock(const scoped_lock&) = delete; // prevent creating a new scoped_lock by copying an existing one
scoped_lock& operator=(const scoped_lock&) = delete; // prevent assigning one scoped_lock to another
};
注釈
adopt_lock_t は、 scoped_lock コンストラクターが呼び出し元スレッドによって既にロックされているミューテックスの所有権を引き受けるべきであることを示すタグ型です。 これにより、ミューテックスをもう一度ロックせずに scoped_lock オブジェクトを作成できます。これは、既にロックを取得していて、 scoped_lockで有効期間を管理したい特定のシナリオで役立ちます。
scoped_lock クラスは、スコープ全体で 1 つ以上のミューテックスのロックとロック解除を管理します。
scoped_lock オブジェクトを作成すると、渡されたミューテックスの所有権が取得されます。
scoped_lock オブジェクトが破棄されると (スコープ外になった場合など)、ミューテックスが解放されます。 これにより、例外がスローされた場合でも、ミューテックスが常に適切に解放されます。
1 つのミューテックスのみをロックする必要がある場合は、 lock_guard または unique_lockの使用を検討してください。 デッドロックのリスクなしに複数のミューテックスを同時にロックする必要がある場合は、 scoped_lock を使用します。
scoped_lock クラスはコピーできません。
scoped_lockに渡されるミューテックス型が 1 つだけの場合、scoped_lockは、その 1 つのミューテックス型を参照するmutex_typeという名前の型エイリアスを提供します。 ただし、2 つ以上のミューテックス型を持つ scoped_lock を作成した場合、 mutex_type エイリアスは存在しません。これは、基になるミューテックス型が 1 つある場合にのみ、 mutex_type が意味を持つからです。 複数のミューテックスでは、公開するミューテックスの種類は 1 つではありません。
コンストラクター
| コンストラクター | 説明 |
|---|---|
scoped_lock(MutexTypes&... m) |
scoped_lock オブジェクトを構築し、指定されたすべてのミューテックスをロックします。 複数のミューテックスが指定されている場合、デッドロック回避アルゴリズムを使用してロックされます。 |
scoped_lock(MutexTypes&... m, adopt_lock_t) |
scoped_lock オブジェクトを構築し、指定されたミューテックスの所有権を採用します。このミューテックスは、呼び出し元のスレッドによって既にロックされている必要があります。 |
デストラクター
| デストラクター | 説明 |
|---|---|
~scoped_lock() |
scoped_lock オブジェクトを破棄し、所有しているすべてのミューテックスを解放します。 |
例
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
std::mutex mutex1;
std::mutex mutex2;
int shared_data1 = 0;
int shared_data2 = 0;
void update_both(int iterations)
{
for (int i = 0; i < iterations; ++i)
{
// Lock both mutexes simultaneously without risk of deadlock
std::scoped_lock lock(mutex1, mutex2);
++shared_data1;
++shared_data2;
}
}
int main()
{
std::vector<std::thread> threads;
for (int i = 0; i < 4; ++i)
{
threads.emplace_back(update_both, 1000);
}
for (auto& t : threads)
{
t.join();
}
std::cout << "shared_data1: " << shared_data1 << '\n';
std::cout << "shared_data2: " << shared_data2 << '\n';
// Output:
// shared_data1: 4000
// shared_data2: 4000
}
必要条件
ヘッダー: <mutex>
名前空間: std