forked from mpavezb/cpp_concurrency
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path05_unique_lock.cpp
More file actions
87 lines (69 loc) · 2.24 KB
/
05_unique_lock.cpp
File metadata and controls
87 lines (69 loc) · 2.24 KB
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <iostream>
#include <mutex>
#include <string>
#include <thread>
// =========================================================
// EXAMPLE 1: Simultaneous Locking to Avoid Deadlock
// =========================================================
class bank_account {
double balance;
std::string name;
std::mutex m;
public:
bank_account(){};
bank_account(double _balance, std::string const &_name)
: balance(_balance), name(_name) {}
bank_account(bank_account const &) = delete;
bank_account &operator=(bank_account const &) = delete;
void withdraw(double amount) {
std::lock_guard<std::mutex> lg(m);
balance += amount;
}
void deposite(double amount) {
std::lock_guard<std::mutex> lg(m);
balance += amount;
}
void transfer(bank_account &from, bank_account &to, double amount) {
std::cout << std::this_thread::get_id()
<< " hold the lock for both mutex \n";
// Unique Lock allows deferral and simultaneous locking
std::unique_lock<std::mutex> ul_1(from.m, std::defer_lock);
std::unique_lock<std::mutex> ul_2(to.m, std::defer_lock);
std::lock(ul_1, ul_2);
from.balance -= amount;
to.balance += amount;
std::cout << "transfer to - " << to.name << " from - " << from.name
<< " end \n";
}
};
void run_code1() {
bank_account account;
bank_account account_1(1000, "james");
bank_account account_2(2000, "Mathew");
std::thread thread_1(&bank_account::transfer, &account, std::ref(account_1),
std::ref(account_2), 500);
std::thread thread_2(&bank_account::transfer, &account, std::ref(account_2),
std::ref(account_1), 200);
thread_1.join();
thread_2.join();
}
// =========================================================
// EXAMPLE 2: Ownership Transfer
// =========================================================
void x_operations() { std::cout << "this is a operation\n"; }
void y_operations() { std::cout << "this is another operation\n"; }
std::mutex m;
std::unique_lock<std::mutex> get_lock() {
std::unique_lock<std::mutex> lk(m);
x_operations();
return lk;
}
void run_code2() {
std::unique_lock<std::mutex> lk(get_lock());
y_operations();
}
int main() {
run_code1();
run_code2();
return 0;
}