table of contents
        
      
      
    - Tumbleweed 2024.07.05-1.3
 - Leap-16.0
 - Leap-15.6
 
| 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 acquired 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 available
  
   (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, returns 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 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.
// 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
    implements 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)
| 2024.06.10 | http://cppreference.com |