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 (optional*) 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
	  The output below  was	 generated  on	a  single-core	machine.  When
       thread1 starts, it
	  enters the loop for the first	time and calls increment() 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	itera-
       tion, 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.

       // Run this code

	#include <iostream>
	#include <mutex>
	#include <shared_mutex>
	#include <syncstream>
	#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.
	    void increment()
	    {
		std::unique_lock lock(mutex_);
		++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_{};
	};

	int main()
	{
	    ThreadSafeCounter counter;

	    auto increment_and_print = [&counter]()
	    {
		for (int i{}; i	!= 3; ++i)
		{
		    counter.increment();
		    std::osyncstream(std::cout)
			<<  std::this_thread::get_id() << ' ' << counter.get()
       << '\n';
		}
	    };

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

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

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		  2024.06.10		  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.1.quarterly>

home | help