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

FreeBSD Manual Pages

  
 
  

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

NAME
       std::shared_mutex - std::shared_mutex

Synopsis
	  Defined in header <shared_mutex>
	  class	shared_mutex;		    (since C++17)

	  The  shared_mutex  class  is a synchronization primitive that	can be
       used to protect
	  shared data from being simultaneously	accessed by multiple  threads.
       In contrast to
	  other	 mutex types which facilitate exclusive	access,	a shared_mutex
       has two levels
	  of access:

	    * shared - several threads can share ownership of the same mutex.

	    * exclusive	- only one thread can own the mutex.

	  If one  thread  has  acquired	 the  exclusive	 lock  (through	 lock,
       try_lock), no other
	  threads can acquire the lock (including the shared).

	  If  one  thread  has	acquired the shared lock (through lock_shared,
       try_lock_shared),
	  no other thread can acquire the exclusive lock, but can acquire  the
       shared lock.

	  Only	when  the  exclusive lock has not been acquired	by any thread,
       the shared lock
	  can be acquired by multiple threads.

	  Within one thread, only one lock (shared or exclusive)  can  be  ac-
       quired at the same
	  time.

	  Shared  mutexes are especially useful	when shared data can be	safely
       read by any
	  number of threads simultaneously, but	a thread may  only  write  the
       same data when no
	  other	thread is reading or writing at	the same time.

	  The shared_mutex class satisfies all requirements of SharedMutex and
	  StandardLayoutType.

Member types
	  Member type				 Definition
	  native_handle_type(not always	present) implementation-defined

Member functions
	  constructor	  constructs the mutex
			  (public member function)
	  destructor	  destroys the mutex
			  (public member function)
	  operator=	  not copy-assignable
	  [deleted]	  (public member function)
		Exclusive locking
	  lock		   locks  the mutex, blocks if the mutex is not	avail-
       able
			  (public member function)
	  try_lock	  tries	to lock	the mutex, returns if the mutex	is not
       available
			  (public member function)
	  unlock	  unlocks the mutex
			  (public member function)

Shared locking
			  locks	the mutex for shared ownership,	blocks if  the
       mutex is	not
	  lock_shared	  available
			  (public member function)
			  tries	 to  lock  the mutex for shared	ownership, re-
       turns if	the mutex
	  try_lock_shared is not available
			  (public member function)
	  unlock_shared	  unlocks the mutex (shared ownership)
			  (public member function)

Native handle
	  native_handle	  returns the underlying implementation-defined	native
       handle object
			  (public member function)

Example
       // Run this code

	#include <iostream>
	#include <mutex>
	#include <shared_mutex>
	#include <thread>

	class ThreadSafeCounter	{
	 public:
	  ThreadSafeCounter() =	default;

	  // Multiple threads/readers can read the counter's value at the same
       time.
	  unsigned int get() const {
	    std::shared_lock lock(mutex_);
	    return value_;
	  }

	  // Only one thread/writer can	increment/write	the counter's value.
	  unsigned int increment() {
	    std::unique_lock lock(mutex_);
	    return ++value_;
	  }

	  // Only one thread/writer can	reset/write the	counter's value.
	  void reset() {
	    std::unique_lock lock(mutex_);
	    value_ = 0;
	  }

	 private:
	  mutable std::shared_mutex mutex_;
	  unsigned int value_ =	0;
	};

	int main() {
	  ThreadSafeCounter counter;

	  auto increment_and_print = [&counter]() {
	    for	(int i = 0; i <	3; i++)	{
	      std::cout	<< std::this_thread::get_id() << ' ' <<	counter.incre-
       ment() << '\n';

	      // Note: Writing to std::cout actually needs to be  synchronized
       as well
	      //  by another std::mutex. This has been omitted to keep the ex-
       ample small.
	    }
	  };

	  std::thread thread1(increment_and_print);
	  std::thread thread2(increment_and_print);

	  thread1.join();
	  thread2.join();
	}

	// Explanation:	The output below was generated on  a  single-core  ma-
       chine. When
	// thread1 starts, it enters the loop for the first time and calls in-
       crement()
	//  followed by	get(). However,	before it can print the	returned value
       to
	// std::cout, the  scheduler  puts  thread1  to	 sleep	and  wakes  up
       thread2,	which
	// obviously has time enough to	run all	three loop iterations at once.
       Back to
	//  thread1,  still in the first loop iteration, it finally prints its
       local copy
	// of the counter's value, which is 1, to std::cout and	then runs  the
       remaining
	//  two	 loop iterations. On a multi-core machine, none	of the threads
       is put to
	// sleep and the output	is more	likely to be in	ascending order.

Possible output:
	123084176803584	2
	123084176803584	3
	123084176803584	4
	123084185655040	1
	123084185655040	5
	123084185655040	6

See also
	  shared_timed_mutex provides shared mutual exclusion facility and im-
       plements	locking
	  (C++14)	     with a timeout
			     (class)
	  shared_lock	     implements	movable	shared mutex ownership wrapper
	  (C++14)	     (class template)
	  unique_lock	     implements	movable	mutex ownership	wrapper
	  (C++11)	     (class template)

http://cppreference.com		  2022.07.31		  std::shared_mutex(3)

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

home | help