Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

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

NAME
       std::scoped_lock	- std::scoped_lock

Synopsis
	  Defined in header <mutex>
	  template< class... MutexTypes	>  (since C++17)
	  class	scoped_lock;

	  The  class scoped_lock is a mutex wrapper that provides a convenient
       RAII-style
	  mechanism for	owning zero or more mutexes  for  the  duration	 of  a
       scoped block.

	  When	a scoped_lock object is	created, it attempts to	take ownership
       of the mutexes
	  it is	given. When control leaves the scope in	which the  scoped_lock
       object was
	  created, the scoped_lock is destructed and the mutexes are released.
       If several
	  mutexes  are	given,	deadlock  avoidance algorithm is used as if by
       std::lock.

	  The scoped_lock class	is non-copyable.

Template parameters
		       the types of the	mutexes	to lock. The types  must  meet
       the Lockable
	  MutexTypes  -	requirements unless sizeof...(MutexTypes)==1, in which
       case the	only
		       type must meet BasicLockable

Member types
	  Member type				  Definition
	  mutex_type (ifsizeof...(MutexTypes)==1) Mutex, the sole type in  Mu-
       texTypes...

Member functions
	  constructor	constructs a scoped_lock, optionally locking the given
       mutexes
			(public	member function)
	  destructor	destructs the scoped_lock object, unlocks the underly-
       ing mutexes
			(public	member function)
	  operator=	not copy-assignable
	  [deleted]	(public	member function)

Notes
	  A  common  beginner error is to "forget" to give a scoped_lock vari-
       able a name, e.g.
	  std::scoped_lock(mtx); (which	default	constructs a scoped_lock vari-
       able named mtx)
	  or std::scoped_lock{mtx}; (which constructs a	prvalue	object that is
       immediately
	  destroyed), thereby not actually constructing	a lock	that  holds  a
       mutex for the rest
	  of the scope.

	   Feature-test	macro	 Value	  Std	    Feature
	  __cpp_lib_scoped_lock	201703L	(C++17)	std::scoped_lock

Example
	  The following	example	uses std::scoped_lock to lock pairs of mutexes
       without
	  deadlock and is RAII-style.

       // Run this code

	#include <chrono>
	#include <functional>
	#include <iostream>
	#include <mutex>
	#include <string>
	#include <thread>
	#include <vector>
	using namespace	std::chrono_literals;

	struct Employee
	{
	    std::vector<std::string> lunch_partners;
	    std::string	id;
	    std::mutex m;
	    Employee(std::string id) : id(id) {}
	    std::string	partners() const
	    {
		std::string ret	= "Employee " +	id + " has lunch partners: ";
		for (int count{}; const	auto& partner :	lunch_partners)
		    ret	+= (count++ ? ", " : "") + partner;
		return ret;
	    }
	};

	void send_mail(Employee&, Employee&)
	{
	    // Simulate	a time-consuming messaging operation
	    std::this_thread::sleep_for(1s);
	}

	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  << " and " << e2.id << " are waiting for
       locks" << std::endl;
	    }

	    {
		// Use std::scoped_lock	to acquire two locks without  worrying
       about
		// other calls to assign_lunch_partner deadlocking us
		// and it also provides	a convenient RAII-style	mechanism

		std::scoped_lock lock(e1.m, e2.m);

		// Equivalent code 1 (using std::lock and std::lock_guard)
		// 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);

		//  Equivalent	code  2	 (if unique_locks are needed, e.g. for
       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);
		{
		    std::lock_guard<std::mutex>	lk(io_mutex);
		    std::cout << e1.id << " and	" << e2.id << "	got locks"  <<
       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");

	    // Assign in parallel threads because mailing  users  about	 lunch
       assignments
	    // takes a long time
	    std::vector<std::thread> threads;
	    threads.emplace_back(assign_lunch_partner,	      std::ref(alice),
       std::ref(bob));
	    threads.emplace_back(assign_lunch_partner,	  std::ref(christina),
       std::ref(bob));
	    threads.emplace_back(assign_lunch_partner,	  std::ref(christina),
       std::ref(alice));
	    threads.emplace_back(assign_lunch_partner,	       std::ref(dave),
       std::ref(bob));

	    for	(auto& thread :	threads)
		thread.join();
	    std::cout << alice.partners() << '\n'  << bob.partners() <<	'\n'
		      <<  christina.partners()	<<  '\n' << dave.partners() <<
       '\n';
	}

Possible output:
	Alice and Bob are waiting for locks
	Alice and Bob got locks
	Christina and Bob are waiting for locks
	Christina and Alice are	waiting	for locks
	Dave and Bob are waiting for locks
	Dave and Bob got locks
	Christina and Alice got	locks
	Christina and Bob got locks
	Employee Alice has lunch partners: Bob,	Christina
	Employee Bob has lunch partners: Alice,	Dave, Christina
	Employee Christina has lunch partners: Alice, Bob
	Employee Dave has lunch	partners: Bob

	  Defect reports

	  The following	behavior-changing defect reports were applied retroac-
       tively to
	  previously published C++ standards.

	     DR	     Applied	to		   Behavior    as    published
       Correct behavior
	  LWG	 2981	 C++17	       redundant    deduction	 guide	  from
       removed
			      scoped_lock<MutexTypes...> was provided

See also
	  unique_lock implements movable mutex ownership wrapper
	  (C++11)     (class template)
	  lock_guard  implements a strictly scope-based	mutex ownership	 wrap-
       per
	  (C++11)     (class template)

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

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=std::scoped_lock&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help