-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
65 lines (54 loc) · 1.53 KB
/
main.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
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <thread>
// This code prints FooBar n times, where "Foo" and "Bar" are printed by different threads.
// The synchronization is achieved with the use of an atomic variable, a condition variable and memory orders.
class Widget {
private:
int n;
std::condition_variable cv;
std::mutex m;
std::atomic_bool is_foo_turn;
public:
Widget(int n) : n(n)
{
is_foo_turn.store(true, std::memory_order_release);
}
void foo (const std::function<void()>& printFoo)
{
for (int i{0}; i < n; i++) {
std::unique_lock<std::mutex> lock(m);
cv.wait(lock, [this]{ return is_foo_turn.load(std::memory_order_acquire); });
printFoo();
is_foo_turn.store(false, std::memory_order_release);
cv.notify_one();
}
}
void bar (const std::function<void()>& printBar)
{
for (int i{0}; i < n; i++) {
std::unique_lock<std::mutex> lock(m);
cv.wait(lock, [this]{ return !is_foo_turn.load(std::memory_order_acquire); });
printBar();
is_foo_turn.store(true, std::memory_order_release);
cv.notify_one();
}
}
};
int main() {
int n;
std::cin >> n;
Widget widget(n);
std::thread f ([&widget]{
widget.foo([]{
std::cout<<"Foo";});
});
std::thread b ([&widget]{
widget.bar([]{
std::cout<<"Bar";});
});
f.join();
b.join();
return 0;
}