C++语法学习笔记四十八:单例设计模式共享数据分析、解决,call_once

Stella981
• 阅读 505

实例代码:

// 

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>

using namespace std;


class A{
public:
};

std::mutex  resource_mutex;
std::once_flag g_flag;  //这是个系统定义的标记


class MyCAS{ //这是一个单例类

    static void CreateInstance(){ //只被调用1次
        m_instance = new MyCAS();
        static CGarhuishou c1;
    }


private:
    MyCAS(){}  //私有化了构造函数

private: 
    static MyCAS * m_instance; //静态成员变量

public:
    static MyCAS *GetInstance(){

        //提高效率
        //a) 如果if (m_instance != nullptr)  条件成立,则肯定表示 m_instance 已经被new过了
        //b) 如果if (m_instance == nullptr) 不代表m_instance一定没被new过

        //if (m_instance == nullptr) //双重锁定(双重检查)
        //{
        //    std::unique_lock<std::mutex> mymutex(resource_mutex); //自动加锁
        //    if (m_instance == nullptr)
        //    {
        //        m_instance = new MyCAS();
        //        static CGarhuishou  c1;
        //    }
        //}
        std::call_once(g_flag, CreateInstance); //两个线程同时执行到这里,其中一个线程要等另外一个线程执行完毕CreateInstance();
        cout << "call_once()执行完毕" << endl;
        return m_instance;
    }

    class CGarhuishou //类中套类,用来释放对象
    {
    public:
        ~CGarhuishou(){  //类的析构函数中
            if (MyCAS::m_instance)
            {
                delete MyCAS::m_instance;
                MyCAS::m_instance = NULL;
            }
        }
    };


    void func(){
        cout << "测试" << endl;
    }
};

MyCAS * MyCAS::m_instance = nullptr;


//线程入口函数
void mythread(){
    cout << "我的线程开始执行了" << endl;
    MyCAS *p_a = MyCAS::GetInstance(); //这里可能就有问题了
    p_a->func();
    cout << "我的线程执行完毕了" << endl;
    return;
}

int main()
{
    //一:设计模式大概谈
    //"设计模式":代码的一些写法(这些写法跟常规写法还不怎么一样):程序灵活,维护起来可能方便,但是别人接管、阅读代码都很痛苦。
    //用“设计模式”理念写出来的代码很晦涩的
    //老外 应付特别大的项目的时候,把项目的开发经验、模块划分经验,总结整理成设计模式(现有开发需求,后有理论总结和整理)
    //设计模式拿到中国来,不太一样,拿着一个程序(项目)往设计模式上套;一个小小的项目,它非要弄几个设计模式进去;本末倒置。
    //设计模式肯定有它独特的优点,要活学活用,不要深陷其中,生搬硬套;


    //二:单例设计模式
    //单例设计模式,使用的频率比较高;
    //单例:整个项目中,有某个或者某些特殊的类,属于该类的对象,我只能创建1个,多了我创建不了;
    //单例类:
    A a1;
    A a2;

    //MyCAS a;
    MyCAS *p_a = MyCAS::GetInstance(); //创建一个对象,返回该类(MyCAS)对象的指针
    p_a->func();

    //三:单例设计模式共享数据问题分析、解决
    //面临的问题:需要在我们自己创建的线程(而不是主线程)中来创建MyCAS这个单例类的对象,这种线程可能不止(最少2个)。
    //我们可能会面临GetInstance()这种成员函数要互斥

    //虽然这两个线程是同一个入口函数,但大家千万要记住,这是两个线程,所以这里会有两个流程(两条通路)同时开始执行mythread这个函数;
    std::thread mytobj1(mythread);
    std::thread mytobj2(mythread);

    mytobj1.join();
    mytobj2.join();


    //四:std::call_once();C++11引入的函数,该函数的第二个参数是一个函数名 a();
    //call_once 功能是能够保证函数a()只被调用一次
    //call_once 具备互斥量这种能力,而且效率上,比互斥量消耗的资源更少;
    //call_once()需要与一个标记结合使用,这个标记 std::once_flag;其实once_flag是一个结构;
    //call_once()就是通过这个标记来决定对应的函数a()是否执行,调用call_once成功后,call_once()就把这个标记设置为一种已调用状态
    //后续再次调用call_once() ,只要once_flag被设置为了“已调用”状态,那么对应的函数a()就不会再被执行了;



    system("pause");
}
点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
2年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Java修道之路,问鼎巅峰,我辈代码修仙法力齐天
<center<fontcolor00FF7Fsize5face"黑体"代码尽头谁为峰,一见秃头道成空。</font<center<fontcolor00FF00size5face"黑体"编程修真路破折,一步一劫渡飞升。</font众所周知,编程修真有八大境界:1.Javase练气筑基2.数据库结丹3.web前端元婴4.Jav
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这