scoped_lock Klasse

Die scoped_lock Klasse erwirbt einen oder mehrere Mutexen auf dem Bau und gibt sie zur Zerstörung frei. Wenn mehrere Mutexes bereitgestellt werden, wird ein Deadlock-Vermeidungsalgorithmus (entspricht std::lock) verwendet, um Deadlocks zu verhindern. In C++17 eingeführt.

Syntax


// 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
};

Bemerkungen

adopt_lock_t ist ein Tagtyp, der angibt, dass der scoped_lock Konstruktor den Besitz von Mutexes übernimmt, die bereits durch den aufrufenden Thread gesperrt sind. Auf diese Weise können Sie ein scoped_lock Objekt erstellen, ohne die Mutexes erneut zu sperren, was in bestimmten Szenarien nützlich sein kann, in denen Sie die Sperren bereits erworben haben und deren Lebensdauer mit einer scoped_lockverwalten möchten.

Die scoped_lock Klasse verwaltet das Sperren und Entsperren eines oder mehrerer Mutexes innerhalb eines Bereichs. Wenn Sie ein scoped_lock Objekt erstellen, erwirbt es den Besitz der an sie übergebenen Mutexes. Wenn das scoped_lock Objekt zerstört wird (z. B. wenn es außerhalb des Gültigkeitsbereichs liegt), werden die Mutexe losgelassen. Dadurch wird sichergestellt, dass Mutexes immer ordnungsgemäß freigegeben werden, auch wenn eine Ausnahme ausgelöst wird.

Wenn Sie nur ein einzelnes Mutex sperren müssen, sollten Sie die Verwendung oder unique_lockdie Verwendung in Betracht ziehenlock_guard. Verwenden Sie diese Funktion scoped_lock , wenn Sie mehrere Mutexes gleichzeitig ohne Gefahr eines Deadlocks sperren müssen.

Die scoped_lock Klasse kann nicht kopiert werden.

Wenn nur ein Mutex-Typ übergeben scoped_lockwird, stellt der scoped_lock Typalias mit dem Namen "Mutex" einen mutex_type Mutex-Typ bereit. Wenn Sie jedoch einen scoped_lock Mit zwei oder mehr Mutex-Typen erstellen, ist der mutex_type Alias nicht vorhanden, da mutex_type nur dann sinnvoll ist, wenn ein einzelner zugrunde liegender Mutex-Typ vorhanden ist. Bei mehreren Mutexen gibt es keinen Mutex-Typ, der verfügbar gemacht werden kann.

Konstruktoren

Konstruktor Beschreibung
scoped_lock(MutexTypes&... m) Erstellt ein scoped_lock Objekt und sperrt alle bereitgestellten Mutexes. Wenn mehrere Mutexes bereitgestellt werden, werden sie mit einem Deadlock-Vermeidungsalgorithmus gesperrt.
scoped_lock(MutexTypes&... m, adopt_lock_t) Erstellt ein scoped_lock Objekt und übernimmt den Besitz der bereitgestellten Mutexes, die bereits durch den aufrufenden Thread gesperrt werden müssen.

Destruktor

Destruktor Beschreibung
~scoped_lock() Zerstört das scoped_lock Objekt und gibt alle eigenen Mutexes frei.

Beispiel

#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
}

Anforderungen

Kopfball:<mutex>

Namespace:std

Siehe auch

lock_guard-Klasse
unique_lock-Klasse
<mutex>