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\n";}}//实例已经存在,直接该实例对象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 addrstd::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

注意:上面的单例模式即直接按下面那样不加锁,不用std::call_once调用,在多线程中会因为线程竞争而导致不正确的结果出现。

//(3)获得本类实例的唯一全局访问点static CSinglton* GetInstance(){//若实例不存在,则尝试创建实例对象if (NULL == pInstance){try {CreateInstance);}catch (...) {std::cout << "CreateInstance error\n";}}//实例已经存在,直接该实例对象return pInstance;}

本文转自:https://blog.csdn.net/c_base_jin/article/details/79307262

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

c++11 call_once 使用方法相关推荐

  1. #error “OpenCV 4.x+ requires enabled C++11 support“解决方法

    #error "OpenCV 4.x+ requires enabled C++11 support"解决方法 参考文章: (1)#error "OpenCV 4.x+ ...

  2. 苹果无线耳机使用方法_苹果手机11新手使用方法

    展开全部 苹果手机11新手使用方法2113: 1.face id相关设置52612113 设置-面容id与密码,找到"注释以5261启用面4102容解锁" face id在使410 ...

  3. mysql8.0安装设置密码_mysql8.0.11安装配置方法图文教程 MySQL8.0新密码认证方式

    本文为大家分享了mysql8.0.11安装配置方法图文教程.MySQL8.0新密码认证方式,供大家参考,具体内容如下 1.前言 Oracle已经发布了MySQL8.0GA,GA在外国就是release ...

  4. 713-C++11容器emplace方法原理剖析

    C++11容器emplace方法的现象 C++11容器的push和insert方法,都匹配了emplace的新的方法,也是用来添加数据的. emplace使用的时候感觉和之前的功能是一样的,都是添加新 ...

  5. seo的11种赚钱方法

    seo的11种赚钱方法 年的时候总结了利用seo的11种赚钱方法,事隔二年,seo几乎进入全民时代,有些seo赚钱方法可能竞争太大,或根本不适合广大seo爱好者操作,小黑哥经过这二年对seo的接触与经 ...

  6. Windows 11 绕过 TPM 方法总结,通用无 TPM 镜像下载 (2023 年 1 月更新)

    在虚拟机.Mac 电脑和 TPM 不符合要求的旧电脑上安装 Windows 11 的通用方法总结 请访问原文链接:https://sysin.org/blog/windows-11-no-tpm/,查 ...

  7. 《Effective C#》读书笔记——条目11:理解短小方法的优势C#语言习惯

    在应用程序开发过程中,开发者都力求写出更加高效的代码.但是当你想手工为C#编译器优化代码时,你的种种优化可能反倒会阻碍JIT进行更加高效的优化.因此,我们最好尽可能的写出最清晰的代码,将优化工作交给J ...

  8. CentOS升级gcc到4.8.2以支持C++11标准的方法

    原来的GCC版本:4.4.7(在用户目录下即可查看,输入命令 gcc -v或g++ -v) 升级步骤: 首先下载4.8.2安装包,输入命令: wget http://gcc.skazkaforyou. ...

  9. 计算机无法安装系统,一招就能搞定“这台电脑无法安装 Windows 11”的解决方法...

    微软已经正式发布了 Windows 11.虽然公开发布为今年晚些时候,但微软的 PC Health Check (中文名电脑健康状况检查)应用程序允许 Windows 10 用户检查他们的计算机是否满 ...

最新文章

  1. python中5个json库的速度对比
  2. netty SimpleChannelInboundHandler类继承使用
  3. 一加7喜迎全局DC调光:长时间看屏不再“辣眼”
  4. mysql5.6安装配置教程_Centos6.8 Mysql5.6 安装配置教程
  5. 【100题】第十二题(特殊的递加)
  6. python批量转换文件编码
  7. python的tab自动补全
  8. 天梯赛座位分布-一点都不垃圾的模拟题,代码长度超过100行的都是傻子
  9. Java实现海报+二维码+二维码中间log+文字合并高清图片
  10. 基于MATLAB的车牌识别实现
  11. js判断鼠标单击或者双击事件
  12. 深入浅出TensorFlow2函数——tf.data.Dataset.padded_batch
  13. iOS中block的详解weakSelf、strongSelf-转自唐巧
  14. 使用腾讯云Ubuntu20.04搭建代理服务器
  15. 简介:Virtual Kubelet
  16. 系统变量和用户变量的区别
  17. 这10个思路,能帮你设计出简单易用的网页
  18. larver php7.0,关于PHP7.0与PHP5.6下Laravel博客应用性能对比分析详解
  19. Cross-Site Scripting XSS 跨站攻击全攻略
  20. PCB设计师需要知道的前5个PCB设计指南-PCB布线布局导致的焊接、装配问题

热门文章

  1. 在电路设计中,这7个接口类型太重要了,我难道不该学学么!
  2. android litepal可以指定存储目录吗,Android数据库LitePal的基本用法详解
  3. 实现verilog设计控制交通灯
  4. 计算机会计综合作业,20年7月东财《通用财务软件X》综合作业(100分)
  5. @scheduled 每30s 执行一次_全球首发5G神U麒麟820,荣耀30S卡位5G档位最强,售价2399起...
  6. hash redis springboot_Redis常见的工作场景使用实战,Redisson分布式锁的实现
  7. quartz 每月一次_Quartz Cron表达式 每周、每月执行一次
  8. java的封装性_Java10-java语法基础(九)——java的封装性
  9. ORA-01940 无法删除当前已连接的用户之解决方案
  10. 转载、Python的编码处理(二)