Skip to content

Commit d963f66

Browse files
committed
Small rework
1 parent 2bb7419 commit d963f66

10 files changed

Lines changed: 47 additions & 32 deletions

File tree

singleton-cherno-example/inc/singleton.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class Singleton {
88
static Singleton& getInstance();
99
static void delInstance();
1010
void func();
11+
1112
private:
1213
Singleton();
1314
~Singleton();

singleton-cherno-example/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#include "singleton.h"
33

44
/*
5-
* Cherno example with static pointer 'global' variable
5+
* Example from Cherno with STATIC GLOBAL VARIABLE
66
* Dynamic memory allocation
77
* Lazy initialization
88
* Singleton is created only after first call of getInstance() and destroyed by calling delInstance()

singleton-classic-dynamic-example/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#include "singleton.h"
33

44
/*
5-
* Example with static pointer member variable
5+
* Example with STATIC MEMBER VARIABLE
66
* Dynamic memory allocation
77
* Lazy initialization
88
* Singleton is created only after first call of getInstance() and destroyed by calling delInstance()

singleton-classic-static-example/inc/singleton.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ class Singleton
1212
}
1313

1414
void func();
15-
~Singleton();
1615

1716
private:
1817
Singleton();
18+
~Singleton();
1919
static Singleton instance; /* Declared static instance as member variable. */
2020
};

singleton-classic-static-example/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#include "singleton.h"
33

44
/*
5-
* Example with static member variable
5+
* Example with STATIC MEMBER VARIABLE
66
* Static memory allocation
77
* Eager initialization
88
* Singleton is created before main() and destroyed after main() call

singleton-dclp-example/inc/singleton.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class Singleton {
1111
static void delInstance();
1212

1313
void func();
14+
1415
private:
1516
Singleton();
1617
~Singleton();

singleton-dclp-example/main.cpp

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,36 @@
11
#include <iostream>
2-
#include <future>
2+
#include <thread>
3+
#include <vector>
34
#include "singleton.h"
45

56
/*
6-
* Singleton with Double-Checked Locking - static pointer member variable
7+
* Example with DOUBLE-CHECKED LOCKING PATTERN (DCLP)
78
* Dynamic memory allocation
89
* Lazy initialization
910
* Singleton is created only after first call of getInstance() and destroyed by calling delInstance()
1011
* 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
1616
*/
1717

1818
int main()
1919
{
2020
std::cout << "--- main start ---" << std::endl;
2121

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([]() {
2927
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+
}
3634

3735
std::cout << "--- main end ---" << std::endl;
3836
}

singleton-meyers-example/inc/singleton.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ class Singleton {
1111
}
1212

1313
void func();
14-
~Singleton();
1514

1615
private:
1716
Singleton();
17+
~Singleton();
1818
};

singleton-meyers-example/main.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,34 @@
11
#include <iostream>
2+
#include <thread>
3+
#include <vector>
24
#include "singleton.h"
35

46
/*
5-
* Meyer’s Singleton - Example with static local variable
7+
* Meyer’s Singleton - Example with STATIC LOCAL VARIABLE
68
* Static memory allocation
79
* Lazy initialization
810
* Singleton is created only after first call of getInstance() and destroyed after main() call
9-
* Thread-safe - Thread safety is guaranteed since C++11. A function-local static variable is initialized exactly once, even in a multi-threaded environment.
11+
* Thread-safe - Thread safety is guaranteed since C++11.
12+
* A function-local static variable is initialized exactly once, even in a multi-threaded environment.
13+
* This is the best and simplest way to implement a singleton in C++11 and later.
1014
*/
1115

1216
int main()
1317
{
14-
std::cout << "--- main start ---" << std::endl;
18+
std::cout << "--- main start ---" << std::endl;
1519

16-
Singleton::getInstance().func();
20+
std::vector<std::thread> threads;
21+
22+
// Launch 10 threads
23+
for (int i = 0; i < 10; ++i) {
24+
threads.emplace_back([]() {
25+
Singleton::getInstance().func();
26+
});
27+
}
28+
29+
for (auto& t : threads) {
30+
t.join();
31+
}
1732

18-
std::cout << "--- main end ---" << std::endl;
33+
std::cout << "--- main end ---" << std::endl;
1934
}

singleton-smart-pointer-example/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
#include "singleton.h"
21
#include <iostream>
32
#include <vector>
43
#include <thread>
4+
#include "singleton.h"
55

66
/*
7-
* Singleton with local static unique pointer
7+
* Example with STATIC LOCAL VARIABLE that is a SMART POINTER
88
* Dynamic memory allocation
99
* Lazy initialization
1010
* Singleton is created in the first call of getInstance() and destroyed automatically after main() call

0 commit comments

Comments
 (0)