01 原理
单例模式即是私有化构造函数,创建时通过类中静态函数获得单一实例的一种特殊类。在多线程下需要加上互斥锁,保证单例模式的创建和析构是原子性的。
由于单例模式的特殊性,这里不讨论其析构函数,个人在具体使用的环境中不需要析构单例模式的实例。
02 结果
创建十个线程来测试。
singleton born
PID:: 0x70000c545000 ------ instance address is:: 0x7fb58f40fb30
PID:: 0x70000c8da000 ------ instance address is:: 0x7fb58f40fb30
PID:: 0x70000c64b000 ------ instance address is:: 0x7fb58f40fb30
PID:: 0x70000c6ce000 ------ instance address is:: 0x7fb58f40fb30
PID:: 0x70000c751000 ------ instance address is:: 0x7fb58f40fb30
PID:: 0x70000c7d4000 ------ instance address is:: 0x7fb58f40fb30
PID:: 0x70000c857000 ------ instance address is:: 0x7fb58f40fb30
PID:: 0x70000c95d000 ------ instance address is:: 0x7fb58f40fb30
PID:: 0x70000c9e0000 ------ instance address is:: 0x7fb58f40fb30
PID:: 0x70000c5c8000 ------ instance address is:: 0x7fb58f40fb30
03 Show me the code
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
// ===========================================
// 用于单例模式的互斥锁
mutex mt;
// 是否存在实例的标识位
bool isExist = false;
// 单例模式
class Singleton {
public:
// 存放实例地址的指针
static Singleton* one_singleton;
// 需要调用实例的地方调用该函数
static Singleton* get_singleton() {
if (isExist) {
return one_singleton;
} else {
lock_guard<mutex> lg(mt);
one_singleton = new Singleton();
cout << "singleton born" << endl;
isExist = true;
return one_singleton;
}
}
// 析构函数
~Singleton() {}
private:
// 构造函数私有
explicit Singleton() {}
};
// static变量类外初始化
Singleton* Singleton::one_singleton = nullptr;
// ==============================================
// 防止终端显示混乱的互斥锁
mutex log;
// 子线程调用函数,获得单例模式实例并输出其内存地址
void* show(void*) {
lock_guard<mutex> lg(log);
Singleton* one = Singleton::get_singleton();
this_thread::sleep_for(chrono::microseconds(10));
cout << "PID:: " << this_thread::get_id() << " ------ instance address is:: " << one << endl;
return nullptr;
}
int main() {
// 创建10个线程调用show函数
for (int i = 0; i < 10; i++) {
pthread_t pthread;
pthread_create(&pthread, NULL, show, NULL);
}
// 主线程延时等待以上线程执行完毕
this_thread::sleep_for(chrono::microseconds(1000));
return 0;
}