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
ヘッダーで定義 <mutex>
template < class Lockable1, class Lockable2, class ... LockableN >
int try_lock ( Lockable1 & lock1, Lockable2 & lock2, LockableN & ... lockn ) ;
(C++11以降)

指定された各 Lockable オブジェクト lock1 lock2 ... lockn を、最初から順に try_lock を呼び出してロックしようと試みます。

try_lock の呼び出しが失敗した場合、 try_lock のそれ以上の呼び出しは行われず、 ロックされたオブジェクトに対して unlock が呼び出され、 ロックに失敗したオブジェクトの 0 ベースのインデックスが返されます。

try_lock の呼び出しが例外を発生させた場合、 再スローされる前にロックされたオブジェクトに対して unlock が呼び出されます。

目次

パラメータ

lock1, lock2, ..., lockn - ロックする Lockable オブジェクト

戻り値

- 1 成功時、またはロックに失敗したオブジェクトの 0 ベースのインデックス値。

以下の例では、別々のスレッドで実行されているカウンターを定期的に集計してリセットするために std::try_lock を使用しています。

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

出力例:

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

関連項目

(C++11)
指定されたミューテックスをロックし、利用できないものがある場合はブロックする
(関数テンプレート)