多线程安全单例模式学习代码 c++11

复制代码
// Singleton.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <mutex>        
#include <iostream>
#include <windows.h>

using namespace std;

/**************************************************************
技术博客
http://www.cnblogs.com/itdef/

技术交流群
群号码:324164944

欢迎c c++ windows驱动爱好者 服务器程序员沟通交流
**************************************************************/

std::mutex gPrintMtx;    // 多线程下 用于打印的互斥量
std::mutex gSingletonmtx;        // Singleton类的互斥量
std::mutex gSamplemtx;        // 示例类的互斥量

// 单例模式类 模板为实际单例类
template<typename T>
class Singleton {
public:
    // 多线程下使用互斥量 注意死锁
    Singleton() {
        std::lock_guard<std::mutex> lck(gSingletonmtx);
        count++;
        if (p == NULL) {
            p = new T();
        }
        std::lock_guard<std::mutex> lock(gPrintMtx);
        //cout << "Singleton ..." << endl;
    }

    T* GetInstance() {
        return p;
    }
    ~Singleton() {
        //    使用计数来决定是否删除实际单例类
        std::lock_guard<std::mutex> lck(gSingletonmtx);
        count--;
        if (p != NULL&&count == 0)
        {
            delete p;
            p = NULL;
            count = 0;
            std::lock_guard<std::mutex> lock(gPrintMtx);
            cout << "~Singleton delete" << endl;
        }
        std::lock_guard<std::mutex> lock(gPrintMtx);
        //cout << "~Singleton ..." << endl;
    }
private:
    static int count;
    static T* p;

};

template<typename T>
T* Singleton<T>::p = NULL;

template<typename T>
int Singleton<T>::count = 0;


// 单例模式的示例类
class Sample {
public:
    // 多线程下使用互斥量 注意死锁
    Sample() { 
        std::lock_guard<std::mutex> lck(gSamplemtx);
        std::lock_guard<std::mutex> lock(gPrintMtx);
        count++; cout << "Sample..." << endl; 
    }
    void GetCount(){ 
        std::lock_guard<std::mutex> lck(gSamplemtx);
        std::lock_guard<std::mutex> lock(gPrintMtx);
        cout << "****Sample::cout = " << count << endl; 
    }
    ~Sample() { 
        std::lock_guard<std::mutex> lck(gSamplemtx);
        std::lock_guard<std::mutex> lock(gPrintMtx);
        cout << "~Sample..." << endl; 
    }
private:
    static int count ;
};

int Sample::count = 0;

void ThreadFunc() {
    //    多个Sample类 单例模式
    Singleton<Sample> a;
    Singleton<Sample> b;
    Singleton<Sample> c;

    // 查看Sample类的计数 验证
    a.GetInstance()->GetCount();
    b.GetInstance()->GetCount();
    c.GetInstance()->GetCount();
}


int main()
{
    const int threadCount = 20; //线程数目 可更改
    std::thread threads[threadCount];

    // 多线程执行函数
    for (int i = 0; i < threadCount; i++)
    {
        threads[i] = std::thread(ThreadFunc);
    }

    // join() 等待
    for (auto& th : threads)
        th.join();

    return 0;
}
复制代码

 

运行显示:

Sample...
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
****Sample::cout = 1
~Sample...
~Singleton delete
请按任意键继续. . .

posted on   itdef  阅读(318)  评论(0编辑  收藏  举报

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话

导航

< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示