Namespaces
Variants

std:: lock

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
lock
(C++11)
(C++11)
(C++11)
(C++11)
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
Definiert im Header <mutex>
template < class Lockable1, class Lockable2, class ... LockableN >
void lock ( Lockable1 & lock1, Lockable2 & lock2, LockableN & ... lockn ) ;
(seit C++11)

Sperrt die gegebenen Lockable Objekte lock1 , lock2 , ... , lockn unter Verwendung eines Deadlock-Vermeidungsalgorithmus, um Deadlocks zu vermeiden.

Die Objekte werden durch eine nicht näher spezifizierte Reihe von Aufrufen von lock , try_lock , und unlock gesperrt. Wenn ein Aufruf von lock oder unlock eine Exception verursacht, wird unlock für alle gesperrten Objekte aufgerufen, bevor die Exception erneut ausgelöst wird.

Inhaltsverzeichnis

Parameter

lock1, lock2, ... , lockn - die Lockable Objekte, die gesperrt werden sollen

Rückgabewert

(keine)

Hinweise

Boost bietet eine Version dieser Funktion an , die eine Sequenz von Lockable -Objekten nimmt, die durch ein Iteratorpaar definiert ist.

std::scoped_lock bietet einen RAII -Wrapper für diese Funktion und wird generell einem direkten Aufruf von std::lock vorgezogen.

Beispiel

Das folgende Beispiel verwendet std::lock , um Paare von Mutexen ohne Deadlock zu sperren.

#include <chrono>
#include <functional>
#include <iostream>
#include <mutex>
#include <string>
#include <thread>
#include <vector>
struct Employee
{
    Employee(std::string id) : id(id) {}
    std::string id;
    std::vector<std::string> lunch_partners;
    std::mutex m;
    std::string output() const
    {
        std::string ret = "Mitarbeiter " + id + " hat Lunch-Partner: ";
        for (auto n{lunch_partners.size()}; const auto& partner : lunch_partners)
            ret += partner + (--n ? ", " : "");
        return ret;
    }
};
void send_mail(Employee&, Employee&)
{
    // Simuliere einen zeitaufwändigen Nachrichtenversand-Vorgang
    std::this_thread::sleep_for(std::chrono::milliseconds
(Keine Übersetzung erforderlich, da der Text innerhalb der HTML-Tags C++-spezifische Begriffe enthält und gemäß den Anweisungen unverändert bleiben muss)(696));
}
void assign_lunch_partner(Employee& e1, Employee& e2)
{
    static std::mutex io_mutex;
    {
        std::lock_guard<std::mutex> lk(io_mutex);
        std::cout << e1.id << " und " << e2.id << " warten auf Sperren" << std::endl;
    }
    // Verwenden Sie std::lock, um zwei Sperren zu erwerben, ohne sich Gedanken über 
    // andere Aufrufe von assign_lunch_partner, die uns blockieren
    {
        std::lock(e1.m, e2.m);
        std::lock_guard<std::mutex> lk1(e1.m, std::adopt_lock);
        std::lock_guard<std::mutex> lk2(e2.m, std::adopt_lock);
    // Äquivalenter Code (falls unique_locks benötigt werden, z.B. für Condition Variables)
    //  std::unique_lock<std::mutex> lk1(e1.m, std::defer_lock);
    //  std::unique_lock<std::mutex> lk2(e2.m, std::defer_lock);
    //  std::lock(lk1, lk2);
    // Überlegene Lösung verfügbar in C++17
    //  std::scoped_lock lk(e1.m, e2.m);
        {
            std::lock_guard<std::mutex> lk(io_mutex);
            std::cout << e1.id << " und " << e2.id << " hat Sperren erhalten" << std::endl;
        }
        e1.lunch_partners.push_back(e2.id);
        e2.lunch_partners.push_back(e1.id);
    }
    send_mail(e1, e2);
    send_mail(e2, e1);
}
int main()
{
    Employee alice("Alice"), bob("Bob"), christina("Christina"), dave("Dave");
    // Parallel in Threads zuweisen, da Benutzer über Essenszuweisungen benachrichtigt werden
    // dauert lange
    std::vector<std::thread> threads;
    threads.emplace_back(assign_lunch_partner, std::ref(alice), std::ref
(Anmerkung: Der Text enthält nur HTML-Tags und C++-spezifische Begriffe, die gemäß den Anweisungen nicht übersetzt werden sollen. Daher bleibt die Ausgabe identisch mit der Eingabe.)(bob));
    threads.emplace_back(assign_lunch_partner, std::ref
(Die Übersetzung bleibt identisch, da gemäß den Anforderungen C++-spezifische Begriffe nicht übersetzt werden sollen und "std::ref" ein C++-spezifischer Term ist)(christina), std::ref(bob));
    threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(alice));
    threads.emplace_back(assign_lunch_partner, std::ref
**Erklärung:**
- HTML-Tags und Attribute wurden unverändert beibehalten
- Der C++-spezifische Begriff `std::ref` wurde nicht übersetzt
- Die Formatierung wurde originalgetreu erhalten
- Der Text innerhalb der Tags wurde nicht verändert, da es sich um Code handelt(dave), std::ref
**Erklärung:**
- HTML-Tags und Attribute wurden unverändert beibehalten
- Der C++-spezifische Begriff `std::ref` wurde nicht übersetzt
- Die Formatierung wurde originalgetreu erhalten
- Der Text innerhalb der Tags wurde nicht verändert(bob));
    for (auto& thread : threads)
        thread.join();
    std::cout << alice.output() << '\n'
              << bob.output() << '\n'
              << christina.output() << '\n'
              << dave.output() << '\n';
}

Mögliche Ausgabe:

Alice und Bob warten auf Sperren
Alice und Bob erhielten Sperren
Christina und Bob warten auf Sperren
Christina und Bob erhielten Sperren
Christina und Alice warten auf Sperren
Dave und Bob warten auf Sperren
Dave und Bob erhielten Sperren
Christina und Alice erhielten Sperren
Mitarbeiter Alice hat Mittagessen-Partner: Bob, Christina 
Mitarbeiter Bob hat Mittagessen-Partner: Alice, Christina, Dave 
Mitarbeiter Christina hat Mittagessen-Partner: Bob, Alice 
Mitarbeiter Dave hat Mittagessen-Partner: Bob

Siehe auch

implementiert beweglichen Mutex-Eigentums-Wrapper
(Klassentemplate)
(C++11)
versucht Eigentum an Mutexen durch wiederholte Aufrufe von try_lock zu erlangen
(Funktionstemplate)
Deadlock-vermeidender RAII-Wrapper für mehrere Mutexe
(Klassentemplate)