Namespaces
Variants

std:: try_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
try_lock
(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
Défini dans l'en-tête <mutex>
template < class Lockable1, class Lockable2, class ... LockableN >
int try_lock ( Lockable1 & lock1, Lockable2 & lock2, LockableN & ... lockn ) ;
(depuis C++11)

Tente de verrouiller chacun des objets Lockable donnés lock1 , lock2 , ... , lockn en appelant try_lock dans l'ordre en commençant par le premier.

Si un appel à try_lock échoue, aucun autre appel à try_lock n'est effectué, unlock est appelé pour tous les objets verrouillés et un index basé sur 0 de l'objet qui n'a pas pu être verrouillé est retourné.

Si un appel à try_lock entraîne une exception, unlock est appelé pour tout objet verrouillé avant de relancer l'exception.

Table des matières

Paramètres

lock1, lock2, ..., lockn - les Lockable objets à verrouiller

Valeur de retour

- 1 en cas de succès, ou 0 -index de base de l'objet qui n'a pas pu être verrouillé.

Exemple

L'exemple suivant utilise std::try_lock pour périodiquement totaliser et réinitialiser des compteurs exécutés dans des threads séparés.

#include <chrono>
#include <functional>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
int main()
{
    int foo_count = 0;
    std::mutex foo_count_mutex;
    int bar_count = 0;
    std::mutex bar_count_mutex;
    int overall_count = 0;
    bool done = false;
    std::mutex done_mutex;
    auto increment = [](int& counter, std::mutex& m, const char* desc)
    {
        for (int i = 0; i < 10; ++i)
        {
            std::unique_lock<std::mutex> lock(m);
            ++counter;
            std::cout << desc << ": " << counter << '\n';
            lock.unlock();
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }
    };
    std::thread increment_foo(increment, std::ref(foo_count), 
        std::ref(foo_count_mutex), "foo");
    std::thread increment_bar(increment, std::ref(bar_count), 
        std::ref(bar_count_mutex), "bar");
    std::thread update_overall([&]()
    {
        done_mutex.lock();
        while (!done)
        {
            done_mutex.unlock();
            int result = std::try_lock(foo_count_mutex, bar_count_mutex);
            if (result == -1)
            {
                overall_count += foo_count + bar_count;
                foo_count = 0;
                bar_count = 0;
                std::cout << "overall: " << overall_count << '\n';
                foo_count_mutex.unlock();
                bar_count_mutex.unlock();
            }
            std::this_thread::sleep_for(std::chrono::seconds(2));
            done_mutex.lock();
        }
        done_mutex.unlock();
    });
    increment_foo.join();
    increment_bar.join();
    done_mutex.lock();
    done = true;
    done_mutex.unlock();
    update_overall.join();
    std::cout << "Done processing\n"
              << "foo: " << foo_count << '\n'
              << "bar: " << bar_count << '\n'
              << "overall: " << overall_count << '\n';
}

Sortie possible :

bar: 1
foo: 1
foo: 2
bar: 2
foo: 3
overall: 5
bar: 1
foo: 1
bar: 2
foo: 2
bar: 3
overall: 10
bar: 1
foo: 1
bar: 2
foo: 2
overall: 14
bar: 1
foo: 1
bar: 2
overall: 17
foo: 1
bar: 1
foo: 2
overall: 20
Done processing
foo: 0
bar: 0
overall: 20

Voir aussi

(C++11)
verrouille les mutex spécifiés, bloque si l'un d'eux n'est pas disponible
(modèle de fonction)