zoukankan      html  css  js  c++  java
  • c++11 call_once 使用方法

    call_once是c++11中引入的新特性,用于保证某个函数只调用一次,即使是多线程环境下,它也可以可靠地完成一次函数调用。特别适用于某个初始化只执行一次的场景

    • 若调用call_once一切顺利,将会翻转once_flag变量的内部状态,再次调用该函数时,所对应的目标函数不会被执行
    • 若调用call_once中发生异常,不会翻转once_flag变量的内部状态,再次调用该函数时,目标函数仍然尝试执行

    下面代码是在win7+vs2015编译器测试通过,演示了如何使用c++11 中的call_once方法

    #include "stdafx.h"
    #include <iostream>  
    #include <chrono>  
    #include <thread> 
    #include <mutex>
    
    //单利模式应用 
    class CSinglton
    {
    private:
        //(1)私有额构造函数
        CSinglton() {}
        //在析构函数中释放实例对象
        ~CSinglton()
        {
            if (pInstance != NULL)
            {
                delete pInstance;
                pInstance = NULL;
            }
        }
    public:
        //(3)获得本类实例的唯一全局访问点
        static CSinglton* GetInstance()
        {
            //若实例不存在,则尝试创建实例对象
            if (NULL == pInstance)
            {
                //call_once object makes sure calling CreateInstance function only one time;
                //it will be safe without lock;
                try 
                {
                    std::call_once(m_flag, CreateInstance);
                }
                catch (...) 
                {
                    std::cout << "CreateInstance error
    ";
                }
    
            }
            //实例已经存在,直接该实例对象
            return pInstance;
        }
    
        static void CreateInstance()
        {
            pInstance = new(std::nothrow) CSinglton();//分配失败,是返回NULL;
            if (NULL == pInstance)
            {
                throw std::exception();
            }
        }
    
    private:
        static CSinglton* pInstance;//(2)唯一实例对象
        static std::once_flag m_flag;
    };
    
    CSinglton*          CSinglton::pInstance = NULL;
    //构造 once_flag 对象,内部状态被设为指示函数仍未被调用。 
    std::once_flag      CSinglton::m_flag;
    
    
    //辅助测试代码
    std::mutex g_mutex;
    void  PrintInstanceAddr()
    {
        std::this_thread::sleep_for(std::chrono::microseconds(1));
    
        //get instance 
        CSinglton* pIns = CSinglton::GetInstance();
    
        //print instance addr
        std::lock_guard<std::mutex> lock(g_mutex);
        std::cout << pIns << std::endl;
    }
    
    
    int main()
    {
        std::thread td[5];
    
        //multhread get instance addr;
        for (int i = 0; i < 5; i++)
        {
            td[i] = std::thread(PrintInstanceAddr);
        }
    
        for (int i = 0; i < 5; i++)
        {
            td[i].join();
        }
    
        return 0;
    }
    

    运行结果:

    0076E778
    0076E778
    0076E778
    0076E778
    0076E778

    参考资料:
    http://zh.cppreference.com/w/cpp/thread/call_once
    http://www.cplusplus.com/reference/mutex/call_once/?kw=call_once

  • 相关阅读:
    【python实现卷积神经网络】池化层实现
    【python实现卷积神经网络】批量归一化层实现
    在CentOS Linux系统上,添加新的端口,启用ssh服务
    linux各文件夹的作用
    断网环境下利用pip安装Python离线安装包
    Python数据分析入门之pandas基础总结
    Git入门私房菜
    python处理json
    Json概述以及python对json的相关操作
    将Sublime Text 添加到鼠标右键菜单的教程方法
  • 原文地址:https://www.cnblogs.com/jinxiang1224/p/8468161.html
Copyright © 2011-2022 走看看