1 //
2 // main.cpp
3 // LeetCode
4 //
5 // Created by Hao on 2017/3/16.
6 // Copyright © 2017年 Hao. All rights reserved.
7 //
8 #include <iostream> // std::cout
9 #include <thread> // std::thread, std::this_thread::sleep_for
10 #include <chrono> // std::chrono::seconds
11 #include <mutex> // std::mutex
12
13 std::mutex mtx; // mutex for critical section
14 int count = 0;
15 int num_count = 0;
16
17 void print_block_0 (int n) {
18 // critical section (exclusive access to std::cout signaled by locking mtx):
19 while (true) {
20 if (count % 3 == 0) {
21 mtx.lock();
22
23 ++ count;
24
25 std::cout << "A" << std::endl;
26
27 mtx.unlock();
28 }
29
30 if (num_count == 3) break;
31 }
32 }
33
34 void print_block_1 (int n) {
35 // critical section (exclusive access to std::cout signaled by locking mtx):
36 while (true) {
37 if (count % 3 == 1) {
38 mtx.lock();
39
40 ++ count;
41
42 std::cout << "B" << std::endl;
43
44 mtx.unlock();
45 }
46
47 if (num_count == 3) break;
48 }
49 }
50
51 void print_block_2 (int n) {
52 // critical section (exclusive access to std::cout signaled by locking mtx):
53 while (true) {
54 if (count % 3 == 2) {
55 mtx.lock();
56
57 ++ num_count; // must be executed prior to the following statement, or else an extra "A" would be printed
58
59 ++ count;
60
61 std::cout << "C" << std::endl;
62
63 // std::this_thread::sleep_for (std::chrono::seconds(1)); // sleep in case that an extra "A" is printed
64
65 mtx.unlock();
66 }
67
68 if (num_count == 3) break;
69 }
70 }
71
72 int main()
73 {
74 std::thread threads[3]; // default-constructed threads
75
76 std::cout << "Spawning 3 threads...
";
77
78 threads[0] = std::thread(print_block_0, 10); // move-assign threads
79 threads[1] = std::thread(print_block_1, 10); // move-assign threads
80 threads[2] = std::thread(print_block_2, 10); // move-assign threads
81
82 std::cout << "Done spawning threads. Now waiting for them to join:
";
83 for (int i=0; i<3; ++i)
84 threads[i].join();
85
86 std::cout << "All threads joined!
";
87
88 return 0;
89 }