Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
La scoped_lock classe acquisisce uno o più mutex sulla costruzione e li rilascia alla distruzione. Quando vengono forniti più mutex, viene usato un algoritmo di prevenzione del deadlock (equivalente a std::lock) per evitare deadlock. Introdotto in C++17.
Sintassi
// 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
};
Osservazioni:
adopt_lock_t è un tipo di tag che indica che il costruttore deve assumere la scoped_lock proprietà dei mutex già bloccati dal thread chiamante. In questo modo è possibile creare un scoped_lock oggetto senza bloccare nuovamente i mutex, che possono essere utili in determinati scenari in cui sono già stati acquisiti i blocchi e si vuole gestire la durata con un oggetto scoped_lock.
La scoped_lock classe gestisce il blocco e lo sblocco di uno o più mutex in un ambito. Quando si crea un scoped_lock oggetto, acquisisce la proprietà dei mutex passati. Quando l'oggetto scoped_lock viene eliminato definitivamente (ad esempio, quando esce dall'ambito), i mutex vengono rilasciati. In questo modo, i mutex vengono sempre rilasciati correttamente, anche se viene generata un'eccezione.
Se è necessario bloccare solo un singolo mutex, è consigliabile usare lock_guard o unique_lock. Usare scoped_lock quando è necessario bloccare più mutex contemporaneamente senza rischi di deadlock.
La scoped_lock classe non è copiabile.
Se viene passato un solo tipo mutex a scoped_lock, scoped_lock fornisce un alias di tipo denominato mutex_type che fa riferimento a quel tipo mutex. Tuttavia, se si crea un scoped_lock oggetto con due o più tipi mutex, l'alias mutex_type non esiste perché mutex_type ha senso solo quando è presente un singolo tipo mutex sottostante. Con più mutex, non esiste un tipo mutex da esporre.
Costruttori
| Costruttore | Descrizione |
|---|---|
scoped_lock(MutexTypes&... m) |
Costruisce un scoped_lock oggetto e blocca tutti i mutex forniti. Se vengono forniti più mutex, questi vengono bloccati usando un algoritmo di prevenzione dei deadlock. |
scoped_lock(MutexTypes&... m, adopt_lock_t) |
Costruisce un scoped_lock oggetto e adotta la proprietà dei mutex forniti, che devono essere già bloccati dal thread chiamante. |
Distruttore
| Distruttore | Descrizione |
|---|---|
~scoped_lock() |
Elimina l'oggetto scoped_lock e rilascia tutti i mutex di proprietà. |
Esempio
#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
}
Requisiti
Intestazione:<mutex>
Spazio dei nomi:std