home | help
std::try_lock(3)	       C++ Standard Libary		std::try_lock(3)

NAME
     std::try_lock - std::try_lock

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

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

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
	(C++11) (function template)

http://cppreference.com 	   2024.06.10			std::try_lock(3)

home | help