Reader-Writer Locks

Contents[Show]

With C++14 came reader-writer locks. The idea is straightforward and promising. Arbitrary reading threads can access the critical region at the same time, but only one thread is allowed to write.

Minimized bottleneck

Reader-writer locks do not solve the fundamental problem - threads competing for access to a critical region. But reader-writer locks help a lot - to minimize the bottleneck. Let's have an example.

 1
 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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// readerWriterLock.cpp

#include <iostream>
#include <map>
#include <shared_mutex>
#include <string>
#include <thread>

std::map<std::string,int> teleBook{{"Dijkstra",1972},{"Scott",1976},{"Ritchie",1983}};

std::shared_timed_mutex teleBookMutex;

void addToTeleBook(const std::string& na, int tele){
  std::lock_guard<std::shared_timed_mutex> writerLock(teleBookMutex);
  std::cout << "\nSTARTING UPDATE " << na;
  std::this_thread::sleep_for(std::chrono::milliseconds(500));
  teleBook[na]= tele;
  std::cout << " ... ENDING UPDATE " << na << std::endl;
}

void printNumber(const std::string& na){
  std::shared_lock<std::shared_timed_mutex> readerLock(teleBookMutex);
  std::cout << na << ": " << teleBook[na];
}

int main(){

  std::cout << std::endl;

  std::thread reader1([]{ printNumber("Scott"); });
  std::thread reader2([]{ printNumber("Ritchie"); });
  std::thread w1([]{ addToTeleBook("Scott",1968); });
  std::thread reader3([]{ printNumber("Dijkstra"); });
  std::thread reader4([]{ printNumber("Scott"); });
  std::thread w2([]{ addToTeleBook("Bjarne",1965); });
  std::thread reader5([]{ printNumber("Scott"); });
  std::thread reader6([]{ printNumber("Ritchie"); });
  std::thread reader7([]{ printNumber("Scott"); });
  std::thread reader8([]{ printNumber("Bjarne"); });

  reader1.join();
  reader2.join();
  reader3.join();
  reader4.join();
  reader5.join();
  reader6.join();
  reader7.join();
  reader8.join();
  w1.join();
  w2.join();

  std::cout << std::endl;

  std::cout << "\nThe new telephone book" << std::endl;
  for (auto teleIt: teleBook){
    std::cout << teleIt.first << ": " << teleIt.second << std::endl;
  }

  std::cout << std::endl;

}

 

The telebook in line 9 is the shared variable, which has to be protected. Eight threads want to read the telephone book, two threads want to modify (lines 30 - 39) it. To access the telephone book at the same time, the reading threads use the std::shared_lock<std::shared_timed_mutex>> in line 22. This is in opposite to the writing threads, which need exclusive access to the critical section. The exclusivity is given by the std::lock_guard<std::shared_timed_mutex>> in line 14. At the end, the program displays (lines 54 - 57) the updated telephone book.

readerWriterLocks

The screenshot  shows that the output of the reading threads overlaps, while the writing thread are executed one after the other. It means that the reading operations are performed at the same time.

That was easy. Too easy.

Undefined behaviour

The program has undefined behaviour. What? Before you continue, stop for a few seconds and think. By the way, the concurrent access of std::cout is not the issue.

The characteristic of a race condition is, that at least two threads access the shared variable at the same time, at least one of them is writer. Exactly what is happening in the program. A characteristic of the ordered associative container is that the reading of the container can modify it. It happens if the element is not available in the container - the case "Bjarne". If "Bjarne" is not found in the telephone book, a pair ("Bjarne",0) will be created from the read operation. For the details, have a look at cppreference.com.

What's next?

In the next post I continue with the thread safe initialisation of data in mulithreading programs.

 

 

 

 

 

 

title page smalltitle page small Go to Leanpub/cpplibrary "What every professional C++ programmer should know about the C++ standard library".   Get your e-book. Support my blog.

 

Tags: lock

Comments   

0 #1 power washing ct 2016-07-09 06:07
Very nice style and design and excellent articles, very little else we need :
D.
Quote
0 #2 in wall speaker wire 2016-08-04 02:15
Wohh exactly what I was searching for, thanks for putting up.
Quote
0 #3 oszukiwac 2016-10-21 06:16
I ɑm not certaіn wҺere you are gettіng youг info, however greɑt topic.
I must spend some time studying moгe or figuring outt mⲟre.
Thank you for wonderful informatіοn I waѕ on thᥱ lookout for thіs іnformation for my mission.
Quote

Add comment


My Newest E-Book

Latest comments

Subscribe to the newsletter (+ pdf bundle)

Blog archive

Source Code

Visitors

Today 729

All 332853

Currently are 238 guests and no members online