0%

boost mutex and lock

Guide

basic

ownership

  • shared ownership
  • exclusive ownership
  • upgrade ownership—>exclusive ownership

mutex

  • boost::mutex enable exclusive access to shared data.
  • boost::shared_mutex enable shared access to shared data.

lock

  • boost::shared_lock
  • boost::unique_lock
  • boost::upgrade_lock
  • boost::upgrade_to_unique_lock

Tips from difference-between-boostunique-lock-and-boostupgrade-lock

The difference between upgrade_lock and unique_lock is simple. An instance of unique_lock is acquiring a full exclusive ownership of a shared_mutex. This means that no one else can get any type of ownership while the unique_lock is alive.

Unlike the unique_lock an instance of upgrade_lock is acquiring an upgrade ownership that exclusive only amongst threads trying to get the same upgrade ownership. All other threads that try to get a shared ownership could acquire it with no conflict until the upgrade_lock is upgraded to unique (with an instance of upgrade_to_unique_lock).

The upgrade_lock is useful when some of threads can be readers only and will not try to promote itself to writers. Otherwise (all readers may try to become writers at some point) upgrade_lock will operate as unique_lock.

conclusions

  • thread-A get shared_lock,other threads cannot get unique_lock,upgrade_lock,but can get shared_lock.(multiple-reader)

  • thread-A get upgrade_lock,other threads cannot get unique_lock,upgrade_lock,but can get shared_lock.

  • upgrade_lock can upgrade to upgrade_to_unique_lock,it’s same as thread-A get unique_lock.

  • thread-A get unique_lock,other threads cannot get unique_lock,upgrade_lock,shared_lock. (single-writer)

code 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
62
63
64
65
#include <iostream>
#include <boost/thread.hpp>
#include <boost/bind.hpp>

typedef boost::shared_lock<boost::shared_mutex> read_lock_t;
typedef boost::unique_lock<boost::shared_mutex> write_lock_t;

typedef boost::upgrade_lock<boost::shared_mutex> upgrade_lock_t;
typedef boost::upgrade_to_unique_lock<boost::shared_mutex> upgrade_to_unique_lock_t;

boost::shared_mutex _access; // read-write access

typedef boost::unique_lock<boost::mutex> exclusive_lock_t;

int data = 0;

void readOnly()
{
read_lock_t rdlock(_access);
std::cout << data << std::endl;
}

void writeOnly()
{
write_lock_t wtlock(_access);
data = 100;
}

//=============================================
// reader and writer
//=============================================
void reader()
{
read_lock_t lock(_access);
// do work here, without anyone having exclusive access

std::cout << data << std::endl;
}

void conditional_writer()
{
upgrade_lock_t lock(_access);
// do work here, without anyone having exclusive access

bool conditional = true; // true/false
if (conditional) {
upgrade_to_unique_lock_t uniqueLock(lock);
// do work here, but now you have exclusive access
data = 100;
}

// do more work here, without anyone having exclusive access
}

void unconditional_writer()
{
write_lock_t lock(_access);
// do work here, with exclusive access
data = 100;
}

int main(int argc, char* argv[])
{
return 0;
}

Reference

History

  • 20180523 created.