File tree Expand file tree Collapse file tree 4 files changed +54
-33
lines changed
Expand file tree Collapse file tree 4 files changed +54
-33
lines changed Original file line number Diff line number Diff line change 55 rm -f * o racing * ~ core racing.sol
66
77racing : racing.cpp
8- ${CXX} -g -std=c++11 -O0 -pthread -Wall -Wextra -L. -o $@ $<
8+ ${CXX} -g -std=c++17 -O0 -pthread -Wall -Wextra -L. -o $@ $<
99
1010racing.sol : solution/racing.sol.cpp
11- ${CXX} -g -std=c++11 -O0 -pthread -Wall -Wextra -L. -o $@ $<
11+ ${CXX} -g -std=c++17 -O0 -pthread -Wall -Wextra -L. -o $@ $<
Original file line number Diff line number Diff line change 11#include < iostream>
22#include < thread>
33
4- int a = 0 ;
5-
6- void inc () {
7- a++;
8- }
9-
10- void inc100 () {
11- for (int i = 0 ; i < 100 ; i++)
12- inc ();
13- }
4+ /*
5+ * This program tries to increment an integer 200 times in two threads.
6+ * Check whether the result is indeed always 200.
7+ */
148
159int main () {
10+ int nError = 0 ;
11+
1612 for (int j = 0 ; j < 1000 ; j++) {
17- a = 0 ;
13+ int a = 0 ;
14+
15+ // Increment the variable a 100 times:
16+ auto inc100 = [&a](){
17+ for (int i = 0 ; i < 100 ; ++i) {
18+ a++;
19+ }
20+ };
21+
22+ // Run with two threads
1823 std::thread t1 (inc100);
1924 std::thread t2 (inc100);
20- for (auto t: {&t1,&t2}) t->join ();
25+ for (auto t : {&t1,&t2}) t->join ();
26+
27+ // Check
2128 if (a != 200 ) {
22- std::cout << a;
29+ std::cout << " Race: " << a << ' ' ;
30+ nError++;
2331 } else {
2432 std::cout << ' .' ;
2533 }
2634 }
2735 std::cout << ' \n ' ;
36+
37+ return nError;
2838}
Original file line number Diff line number Diff line change 22#include < thread>
33#include < mutex>
44
5- int a = 0 ;
6- std::mutex m;
7-
8- void inc () {
9- std::lock_guard<std::mutex> guard (m);
10- a++;
11- }
12-
13- void inc100 () {
14- for (int i = 0 ; i < 100 ; i++)
15- inc ();
16- }
5+ /*
6+ * This program tries to increment an integer 200 times in two threads.
7+ * We fix the race condition by locking a mutex before each increment.
8+ */
179
1810int main () {
11+ int nError = 0 ;
12+
1913 for (int j = 0 ; j < 1000 ; j++) {
20- a = 0 ;
14+ int a = 0 ;
15+ std::mutex aMutex;
16+
17+ // Increment the variable a 100 times:
18+ auto inc100 = [&a,&aMutex](){
19+ for (int i = 0 ; i < 100 ; ++i) {
20+ std::scoped_lock lock{aMutex};
21+ a++;
22+ }
23+ };
24+
25+ // Run with two threads
2126 std::thread t1 (inc100);
2227 std::thread t2 (inc100);
23- for (auto t: {&t1,&t2}) t->join ();
28+ for (auto t : {&t1,&t2}) t->join ();
29+
30+ // Check
2431 if (a != 200 ) {
25- std::cout << a;
32+ std::cout << " Race: " << a << ' ' ;
33+ nError++;
2634 } else {
2735 std::cout << ' .' ;
2836 }
2937 }
3038 std::cout << ' \n ' ;
39+
40+ return nError;
3141}
Original file line number Diff line number Diff line change 9292 \pause
9393 \begin {block }{The objects}
9494 \begin {description }[labelwidth=1.8cm]
95- \item [std::mutex] in the mutex header
95+ \item [std::mutex] in the mutex header. \textbf { Mut }ual \textbf { ex }clusion
9696 \item [std::scoped\_ lock] RAII to lock and unlock automatically
9797 \item [std::unique\_ lock] same, but can be released/relocked explicitly
9898 \end {description }
114114 \frametitlecpp [17]{Mutexes and Locks}
115115 \begin {block }{Good practice}
116116 \begin {itemize }
117- \item Always use \texttt {scoped\_ lock } (\cpp 11: \texttt {lock\_ guard })
117+ \item Generally use \texttt {scoped\_ lock } (\cpp 11: \texttt {lock\_ guard })
118118 \item Hold as short as possible, wrap critical section in "\texttt{\string{ \string}}"
119119 \item Only if manual control needed, use \texttt {unique\_ lock }
120120 \end {itemize }
133133\end {frame }
134134
135135\begin {frame }[fragile]
136- \frametitle {Mutexes}
136+ \frametitle {Mutexes and Locks }
137137 \begin {alertblock }{Exercise Time}
138138 \begin {itemize }
139139 \item Go to code/race
179179 \frametitlecpp [11]{How to avoid dead locks}
180180 \begin {block }{Possible solutions}
181181 \begin {itemize }
182+ \item \cpp 17: \mintinline {cpp}{std::scoped_lock lock{m1, m2};} comes with deadlock-avoidance algorithm
182183 \item Never take several locks
183184 \begin {itemize }
184185 \item Or add master lock protecting the locking phase
You can’t perform that action at this time.
0 commit comments