zoukankan      html  css  js  c++  java
  • 多线程安全单例模式学习代码 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
    请按任意键继续. . .

  • 相关阅读:
    优化代码及其他注意事项---好好做人吧
    el-table里面的列需要对比两个返回参数
    怎么样使element ui 的table某列变色
    怎么在app上添加图标和文字
    app内嵌H5的上传图片的功能
    将本地的链接在手机上查看
    《概率统计》2.离散型随机变量:分布与数字特征
    《概率统计》1.理论基石:条件概率、独立性与贝叶斯
    pygame(1):基本使用(更新中~~~)
    详解DataFrame、Series的replace方法
  • 原文地址:https://www.cnblogs.com/itdef/p/5004877.html
Copyright © 2011-2022 走看看