-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathAtomicBusyWaitMultithreadedPrintFunc.cpp
60 lines (51 loc) · 1.27 KB
/
AtomicBusyWaitMultithreadedPrintFunc.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
/**
* Implementation of atomic busy-wait approach
* to synchronize each printing call to console.
*
* This should be fine if you know ahead that there would be
* a very brief time waiting, so it won't busy spin too hard.
*
* This uses C++17 because of utilization of fold-expression
* in C++17 in ts_print() function. It would need more effort
* if implement in older version of C++ standard.
*
* Compile with
* g++ -std=c++17 <source-file> -lpthread
*/
#include <thread>
#include <iostream>
#include <utility>
#include <atomic>
static std::atomic_flag gPrintLock = ATOMIC_FLAG_INIT;
template<typename... Args>
static void ts_print(Args&&... args)
{
// spin-lock, that's fine for our usecase
while (gPrintLock.test_and_set(std::memory_order_acquire))
;
((std::cout << std::forward<Args>(args)), ...) << std::endl;
// release the lock
gPrintLock.clear();
}
struct MyCallable
{
int value;
MyCallable(): value(0) {}
MyCallable(int value_): value(value_) {}
void operator()(const char* context) const
{
ts_print("[", context, "] ", value);
}
};
int main()
{
std::thread t1(MyCallable(), "t1");
std::thread t2(MyCallable(), "t2");
std::thread t3(MyCallable(10), "t3");
std::thread t4(MyCallable(10), "t4");
t1.join();
t2.join();
t3.join();
t4.join();
return 0;
}