Shared Mutex C++ Introduction














































Shared Mutex C++ Introduction



Introduction Shared Mutex

In my previous article, I wrote about mutex library which provided mutual exclusiveness and how they avoid race conditions by allowing only one thread to access data simultaneously.

However here,shared mutex class adds the ability to provide shared access to the mutex. 

This allows one to, for example, provide read access to a resource by multiple threads, while a writing thread would still be able to gain exclusive access.

While a regular mutex exposes 3 methods: lockunlock and try_lock,

Shared Mutex however adds 3 more methods::
  • lock_shared 
  • try_lock_shared
  • unlock_shared
where shared means  several threads can share ownership of the same mutex.

Point to note::

  • If one thread has acquired the exclusive lock (through locktry_lock), no other threads can acquire the lock (including the shared).
  • If one thread has acquired the shared lock (through lock_sharedtry_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 Mutex  is useful in situations where we may allow multiple parallel readers or one writer to operate on a block of data.

The member functions are same as mentioned in the previous article,with the additon of the shared functions:

  • lock_shared locks the mutex for shared ownership, blocks if the mutex is not available
  • try_lock_shared - tries to lock the mutex for shared ownership, returns if the mutex is not available
  • unlock_shared - unlocks the mutex (shared ownership).

A Sample Program



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <thread>
#include <shared_mutex>

int value = 0;
std::shared_mutex mutex;

// Reads the value and sets v to that value
void readValue(int& v) {
  mutex.lock_shared();
  // Simulate some latency/time to run
  std::this_thread::sleep_for(std::chrono::seconds(1));
  v = value;
  mutex.unlock_shared();
}

// Sets value to v
void setValue(int v) {
  mutex.lock();
  // Simulate some latency/time to run
  std::this_thread::sleep_for(std::chrono::seconds(1));
  value = v;
  mutex.unlock();
}

int main() {
  int read1;
  int read2;
  int read3;
  std::thread t1(readValue, std::ref(read1));
  std::thread t2(readValue, std::ref(read2));
  std::thread t3(readValue, std::ref(read3));
  std::thread t4(setValue, 1);

  t1.join();
  t2.join();
  t3.join();
  t4.join();

  std::cout << read1 << "\n";
  std::cout << read2 << "\n";
  std::cout << read3 << "\n";
  std::cout << value << "\n";
}

Here if we do not use shared mutex,the profram takes 4 sec to run as each thread takes around 1 sec to run,
however using shared mutex reduces the time taken to 2 sec as it allows threads t1t2 and t3 can access the    data at the same time.
 The only thread that will be waiting for 1 second is t4.




Comments