-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlocking.cpp
153 lines (116 loc) · 3.32 KB
/
locking.cpp
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Race conditions example
// Adam Sampson <[email protected]>
#include <iostream>
#include <iomanip>
#include <thread>
#include <vector>
#include <chrono>
#include <mutex>
#include "account.h"
// Import things we need from the standard library
using std::cout;
using std::endl;
using std::vector;
using std::thread;
using std::mutex;
using std::unique_lock;
using std::chrono::duration_cast;
using std::chrono::milliseconds;
using std::chrono::steady_clock;
Account bill;
mutex bill_mutex;
void bill_add()
{
for (auto i = 0; i < 1000000; ++i)
bill.add(17, 29);
}
void bill_add_mutex() {
for (auto i = 0; i < 1000000; ++i)
{ // critical
bill_mutex.lock();
bill.add(17, 29);
bill_mutex.unlock();
}
}
void bill_add_mutex_unique() {
for (auto i = 0; i < 1000000; ++i)
{ // critical
unique_lock<mutex> lock(bill_mutex);
bill.add(17, 29);
}
}
vector<double> no_locks()
{
cout << "Starting no_locks()" << endl;
const auto start = steady_clock::now();
const uint16_t thread_count = 10;
std::vector<thread> threads;
for (auto i = 0; i < thread_count; ++i)
threads.emplace_back(bill_add);
for (auto i = 0; i < thread_count; ++i)
threads[i].join();
const auto end = steady_clock::now();
cout << "Finished no_locks()" << endl;
vector<double> vals;
// time
vals.emplace_back(static_cast<double>(duration_cast<milliseconds>(end - start).count()));
// value
vals.emplace_back(bill.total());
return vals;
}
vector<double> bill_add_mutexes()
{
cout << "Starting bill_add_mutexes()" << endl;
const auto start = steady_clock::now();
const uint16_t thread_count = 10;
std::vector<thread> threads;
for (auto i = 0; i < thread_count; ++i)
threads.emplace_back(bill_add_mutex);
for (auto i = 0; i < thread_count; ++i)
threads[i].join();
const auto end = steady_clock::now();
cout << "Finished bill_add_mutexes()" << endl;
vector<double> vals;
// time
vals.emplace_back(static_cast<double>(duration_cast<milliseconds>(end - start).count()));
// value
vals.emplace_back(bill.total());
return vals;
}
vector<double> unique_lock_mutex() {
cout << "Starting unique_lock_mutex()" << endl;
const auto start = steady_clock::now();
const uint16_t thread_count = 10;
std::vector<thread> threads;
for (auto i = 0; i < thread_count; ++i)
threads.emplace_back(bill_add_mutex_unique);
for (auto i = 0; i < thread_count; ++i)
threads[i].join();
auto end = steady_clock::now();
cout << "Finished unique_lock_mutex()" << endl;
vector<double> vals;
// time
vals.emplace_back(static_cast<double>(duration_cast<milliseconds>(end - start).count()));
// value
vals.emplace_back(bill.total());
return vals;
}
int main(int argc, char* argv[])
{
const auto no_locks_time = no_locks();
bill.reset_total();
const auto mutexes_time = bill_add_mutexes();
bill.reset_total();
const auto unique_lock_time = unique_lock_mutex();
cout << std::fixed << std::setprecision(2) << endl;
cout << "No locks:" << endl
<< "Time: " << no_locks_time[0] << " ms" << endl
<< "Value: " << no_locks_time[1] << " GBP" << endl << endl;
cout << "Mutexes:" << endl
<< "Time: " << mutexes_time[0] << " ms" << endl
<< "Value: " << mutexes_time[1] << " GBP" << endl << endl;
cout << "Unique locks:" << endl
<< "Time: " << unique_lock_time[0] << " ms" << endl
<< "Value: " << unique_lock_time[1] << " GBP" << endl << endl;
return 0;
}