Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La scoped_lock clase adquiere una o varias exclusión mutuas en la construcción y las libera en la destrucción. Cuando se proporcionan varias exclusión mutuas, se usa un algoritmo de prevención de interbloqueos (equivalente a std::lock) para evitar interbloqueos. Introducido en C++17.
Sintaxis
// 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
};
Observaciones
adopt_lock_t es un tipo de etiqueta que indica que el constructor debe asumir la scoped_lock propiedad de las exclusión mutuas que ya están bloqueadas por el subproceso que realiza la llamada. Esto le permite crear un scoped_lock objeto sin volver a bloquear las exclusión mutuas, lo que puede ser útil en determinados escenarios en los que ya ha adquirido los bloqueos y desea administrar su duración con un scoped_lock.
La scoped_lock clase administra el bloqueo y el desbloqueo de una o varias exclusiones mutuas a lo largo de un ámbito. Al crear un scoped_lock objeto, adquiere la propiedad de las exclusión mutuas que se le pasan. Cuando el scoped_lock objeto se destruye (por ejemplo, cuando sale del ámbito), se liberan las exclusión mutuas. Esto garantiza que las exclusión mutuas siempre se libere correctamente, incluso si se produce una excepción.
Si necesita bloquear solo una exclusión mutua, considere la posibilidad de usar lock_guard o unique_lock. Úselo scoped_lock cuando necesite bloquear varias exclusión mutuas simultáneamente sin riesgo de interbloqueo.
La scoped_lock clase no se puede copiar.
Si solo se pasa un tipo de exclusión mutua a scoped_lock, scoped_lock proporciona un alias de tipo denominado mutex_type que hace referencia a ese tipo de exclusión mutua. Sin embargo, si crea un scoped_lock con dos o más tipos de exclusión mutua, el mutex_type alias no existe porque mutex_type solo tiene sentido cuando hay un único tipo de exclusión mutua subyacente. Con varias exclusión mutuas, no hay un tipo de exclusión mutua que exponer.
Constructores
| Constructor | Descripción |
|---|---|
scoped_lock(MutexTypes&... m) |
Construye un scoped_lock objeto y bloquea todas las exclusión mutuas proporcionadas. Si se proporcionan varias exclusión mutuas, se bloquean mediante un algoritmo de prevención de interbloqueos. |
scoped_lock(MutexTypes&... m, adopt_lock_t) |
Construye un scoped_lock objeto y adopta la propiedad de las exclusión mutuas proporcionadas, que ya deben estar bloqueadas por el subproceso que realiza la llamada. |
Destructor
| Destructor | Descripción |
|---|---|
~scoped_lock() |
Destruye el scoped_lock objeto y libera todas las exclusión mutuas propiedad. |
Ejemplo
#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
}
Requisitos
Encabezado: <mutex>
Espacio de nombres: std