std::try_lock (3) - Linux Manuals

std::try_lock: std::try_lock

NAME

std::try_lock - std::try_lock

Synopsis


Defined in header <mutex>
template< class Lockable1, class Lockable2, class... LockableN> (since C++11)
int try_lock( Lockable1& lock1, Lockable2& lock2, LockableN&... lockn);


Tries to lock each of the given Lockable objects lock1, lock2, ..., lockn by calling try_lock in order beginning with the first.
If a call to try_lock fails, no further call to try_lock is performed, unlock is called for any locked objects and a 0-based index of the object that failed to lock is returned.
If a call to try_lock results in an exception, unlock is called for any locked objects before rethrowing.

Parameters


lock1, lock2, ... , lockn - the Lockable objects to lock

Return value


-1 on success, or 0-based index value of the object that failed to lock.

Example


The following example uses std::try_lock to periodically tally and reset counters running in separate threads.
// Run this code


  #include <mutex>
  #include <vector>
  #include <thread>
  #include <iostream>
  #include <functional>
  #include <chrono>


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

Possible output:


  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

See also


lock locks specified mutexes, blocks if any are unavailable
        (function template)
(C++11)