|
1 | 1 | #include <iostream> |
2 | | -#include <future> |
| 2 | +#include <thread> |
| 3 | +#include <vector> |
3 | 4 | #include "singleton.h" |
4 | 5 |
|
5 | 6 | /* |
6 | | -* Singleton with Double-Checked Locking - static pointer member variable |
| 7 | +* Example with DOUBLE-CHECKED LOCKING PATTERN (DCLP) |
7 | 8 | * Dynamic memory allocation |
8 | 9 | * Lazy initialization |
9 | 10 | * Singleton is created only after first call of getInstance() and destroyed by calling delInstance() |
10 | 11 | * DCLP is designed to add efficient thread-safety to initialization of a shared resource (such as a Singleton), but it has a problem: it’s not reliable |
11 | | -* DCLP can fail for different reasons |
12 | | -* https://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf |
13 | | -* Multiple threads can read instance concurrently, and since instance is a raw pointer with no memory ordering guarantees, |
14 | | -* this is a data race and triggers undefined behavior in C++. |
15 | | -* A pattern (Double-Checked Locking) that was obsoleted by C++11. |
| 12 | +* DCLP can fail for different reasons: Multiple threads can read instance concurrently, |
| 13 | +* and since instance is a raw pointer with no memory ordering guarantees, this is a data race and triggers undefined behavior in C++. |
| 14 | +* This pattern (Double-Checked Locking) was obsoleted by C++11. |
| 15 | +* https://www.aristeia.com/Papers/DDJ_Jul_Aug_2004 |
16 | 16 | */ |
17 | 17 |
|
18 | 18 | int main() |
19 | 19 | { |
20 | 20 | std::cout << "--- main start ---" << std::endl; |
21 | 21 |
|
22 | | - Singleton::getInstance().func(); |
23 | | - |
24 | | - auto async1 = std::async(std::launch::async, []() { |
25 | | - Singleton::getInstance().func(); |
26 | | - }); |
27 | | - |
28 | | - auto async2 = std::async(std::launch::async, []() { |
| 22 | + std::vector<std::thread> threads; |
| 23 | + |
| 24 | + // Launch 10 threads |
| 25 | + for (int i = 0; i < 10; ++i) { |
| 26 | + threads.emplace_back([]() { |
29 | 27 | Singleton::getInstance().func(); |
30 | | - }); |
31 | | - |
32 | | - async1.wait(); |
33 | | - async2.wait(); |
34 | | - |
35 | | - Singleton::delInstance(); |
| 28 | + }); |
| 29 | + } |
| 30 | + |
| 31 | + for (auto& t : threads) { |
| 32 | + t.join(); |
| 33 | + } |
36 | 34 |
|
37 | 35 | std::cout << "--- main end ---" << std::endl; |
38 | 36 | } |
0 commit comments