File tree Expand file tree Collapse file tree 5 files changed +47
-28
lines changed Expand file tree Collapse file tree 5 files changed +47
-28
lines changed Original file line number Diff line number Diff line change 8
8
rm -f * o $(PROGRAM_NAME ) * ~ core $(PROGRAM_NAME ) .sol
9
9
10
10
$(PROGRAM_NAME ) : $(PROGRAM_NAME ) .cpp
11
- ${CXX} -g -std=c++17 -O2 -pthread -Wall -Wextra -L. -o $@ $<
11
+ ${CXX} ${CXXFLAGS} -g -std=c++17 -O2 -pthread -Wall -Wextra -L. -o $@ $<
12
12
13
13
$(PROGRAM_NAME ) .sol : solution/$(PROGRAM_NAME ) .sol.cpp
14
- ${CXX} -g -std=c++17 -O2 -pthread -Wall -Wextra -L. -o $@ $<
14
+ ${CXX} ${CXXFLAGS} -g -std=c++17 -O2 -pthread -Wall -Wextra -L. -o $@ $<
Original file line number Diff line number Diff line change 1
1
2
2
## Instructions
3
3
4
- * Compile, run many times, see what happens
5
- * E.g. in bash, use: ` while true; do ./racing; done `
6
- * (Optional) You can use ` valgrind --tool=helgrind ./racing ` to proof your assumption
4
+ * Compile and run the executable, see if it races
5
+ * If you have a bash shell, try ` ./run ./racing ` , which keeps invoking the executable
6
+ until a race condition is detected
7
+ * (Optional) You can use ` valgrind --tool=helgrind ./racing ` to prove your assumption
8
+ * (Optional) If your operating system supports it, recompile with thread sanitizer.
9
+ With Makefile, use e.g. ` make CXXFLAGS="-fsanitize=thread" `
7
10
* Use a mutex to fix the issue
8
11
* See the difference in execution time
9
- * (Optional) Check agan with ` valgrind ` if the problem is fixed
12
+ * (Optional) Check again with ` valgrind ` or thread sanitizer if the problem is fixed
Original file line number Diff line number Diff line change 1
1
#include < iostream>
2
2
#include < thread>
3
+ #include < vector>
3
4
4
5
/*
5
- * This program tries to increment an integer 200 times in two threads.
6
- * Check whether the result is indeed always 200.
6
+ * This program tries to increment an integer 100 times from multiple threads.
7
+ * If the result comes out at 100*nThread, it stays silent, but it will print
8
+ * an error if a race condition is detected.
9
+ * If you don't see it racing, try ./run ./racing, which keeps invoking the
10
+ * executable until a race condition is detected.
7
11
*/
8
12
13
+ constexpr unsigned int nThread = 2 ;
14
+
9
15
int main () {
10
16
int nError = 0 ;
11
17
@@ -19,20 +25,17 @@ int main() {
19
25
}
20
26
};
21
27
22
- // Run with two threads
23
- std::thread t1 (inc100) ;
24
- std::thread t2 (inc100);
25
- for (auto t : {&t1,&t2}) t-> join ();
28
+ // Start up all threads:
29
+ std::vector<std:: thread> threads ;
30
+ for ( unsigned int i = 0 ; i < nThread; ++i) threads. emplace_back (inc100);
31
+ for (auto & thread : threads) thread. join ();
26
32
27
33
// Check
28
- if (a != 200 ) {
29
- std::cout << " Race: " << a << ' ' ;
34
+ if (a != nThread * 100 ) {
35
+ std::cerr << " Race detected! Result : " << a << ' \n ' ;
30
36
nError++;
31
- } else {
32
- std::cout << ' .' ;
33
37
}
34
38
}
35
- std::cout << ' \n ' ;
36
39
37
40
return nError;
38
41
}
Original file line number Diff line number Diff line change
1
+ #! /bin/bash
2
+
3
+ PROGRAM=" ./racing"
4
+ if [ $# -ge 1 ]; then
5
+ PROGRAM=$1
6
+ fi
7
+
8
+ while true ; do
9
+ $PROGRAM || break ;
10
+ done
Original file line number Diff line number Diff line change 1
1
#include < iostream>
2
2
#include < thread>
3
+ #include < vector>
3
4
#include < mutex>
4
5
5
6
/*
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.
7
+ * This program tries to increment an integer 100 times from multiple threads.
8
+ * If the result comes out at 100*nThread, it stays silent, but it will print
9
+ * an error if a race condition is detected.
10
+ * To run it in a loop, use
11
+ * ./run ./racing.sol
8
12
*/
9
13
14
+ constexpr unsigned int nThread = 2 ;
15
+
10
16
int main () {
11
17
int nError = 0 ;
12
18
@@ -22,20 +28,17 @@ int main() {
22
28
}
23
29
};
24
30
25
- // Run with two threads
26
- std::thread t1 (inc100) ;
27
- std::thread t2 (inc100);
28
- for (auto t : {&t1,&t2}) t-> join ();
31
+ // Start up all threads:
32
+ std::vector<std:: thread> threads ;
33
+ for ( unsigned int i = 0 ; i < nThread; ++i) threads. emplace_back (inc100);
34
+ for (auto & thread : threads) thread. join ();
29
35
30
36
// Check
31
- if (a != 200 ) {
32
- std::cout << " Race: " << a << ' ' ;
37
+ if (a != nThread * 100 ) {
38
+ std::cerr << " Race detected! Result : " << a << ' \n ' ;
33
39
nError++;
34
- } else {
35
- std::cout << ' .' ;
36
40
}
37
41
}
38
- std::cout << ' \n ' ;
39
42
40
43
return nError;
41
44
}
You can’t perform that action at this time.
0 commit comments