C++11多线程中std::call_once的使用
C++11中的std::call_once函数位于<mutex>头文件中。
在多线程编程中,有时某个任务只需要执行一次,此时可以用C++11中的std::call_once函数配合std::once_flag来实现。如果多个线程需要同时调用某个函数,std::call_once可以保证多个线程对该函数只调用一次。也可用在解决线程安全的单例模式。
template<class Callable, class... Args >
void call_once(std::once_flag& flag, Callable&& f, Args&&... args );
std::call_once: Executes the Callable object f exactly once, even if called from several threads.Each group of call_once invocations that receives the same std::once_flag object will meet the following requirements:
(1). Exactly one execution of exactly one of the functions (passed as f to the invocations in the group) is performed. It is undefined which function will be selected for execution. The selected function runs in the same thread as the call_once invocation it was passed to.
(2). No invocation in the group returns before the above-mentioned execution of the selected function is completed successfully, that is, doesn't exit via an exception.
(3). If the selected function exits via exception, it is propagated to the caller. Another function is then selected and executed.
下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:
#include "call_once.hpp"
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
#include <future>/*
template< class Callable, class... Args >
void call_once( std::once_flag& flag, Callable&& f, Args&&... args );Calls fn passing args as arguments, unless another thread has already executed
(or is currently executing) a call to call_once with the same flag.If another thread is already actively executing a call to call_once with the same flag,
it causes a passive execution: Passive executions do not call fn but do not return until
the active execution itself has returned, and all visible side effects are synchronized at
that point among all concurrent calls to this function with the same flag.If an active call to call_once ends by throwing an exception (which is propagated
to its calling thread) and passive executions exist, one is selected among these
passive executions, and called to be the new active call instead.Note that once an active execution has returned, all current passive executions
and future calls to call_once (with the same flag) also return without becoming active executions.The active execution uses decay copies of the lvalue or rvalue references of fn and args,
ignoring the value returned by fn.
*/namespace call_once_ {
/
// reference: http://en.cppreference.com/w/cpp/thread/call_once
namespace {
std::once_flag flag1, flag2;void simple_do_once()
{std::call_once(flag1, [](){ std::cout << "Simple example: called once\n"; });
}void may_throw_function(bool do_throw)
{if (do_throw) {std::cout << "throw: call_once will retry\n"; // this may appear more than oncethrow std::exception();}std::cout << "Didn't throw, call_once will not attempt again\n"; // guaranteed once
}void do_once(bool do_throw)
{try {std::call_once(flag2, may_throw_function, do_throw);}catch (...) {}
}
}int test_call_once_1()
{std::thread st1(simple_do_once);std::thread st2(simple_do_once);std::thread st3(simple_do_once);std::thread st4(simple_do_once);st1.join();st2.join();st3.join();st4.join();/*std::thread t1(do_once, true);std::thread t2(do_once, true);std::thread t3(do_once, false);std::thread t4(do_once, true);t1.join();t2.join();t3.join();t4.join();*/return 0;
}///
// reference: http://www.cplusplus.com/reference/mutex/call_once/
namespace {
int winner;
void set_winner(int x) { winner = x; }
std::once_flag winner_flag;void wait_1000ms(int id) {// count to 1000, waiting 1ms between increments:for (int i = 0; i<1000; ++i)std::this_thread::sleep_for(std::chrono::milliseconds(1));// claim to be the winner (only the first such call is executed):std::call_once(winner_flag, set_winner, id);
}
}int test_call_once_2()
{std::thread threads[10];// spawn 10 threads:for (int i = 0; i<10; ++i)threads[i] = std::thread(wait_1000ms, i + 1);std::cout << "waiting for the first among 10 threads to count 1000 ms...\n";for (auto& th : threads) th.join();std::cout << "winner thread: " << winner << '\n';return 0;
}// reference: http://www.modernescpp.com/index.php/thread-safe-initialization-of-a-singleton
namespace {
/*constexpr*/const auto tenMill = 10000;class MySingleton{
public:static MySingleton& getInstance(){std::call_once(initInstanceFlag, &MySingleton::initSingleton);// volatile int dummy{};return *instance;}
private:MySingleton() = default;~MySingleton() = default;MySingleton(const MySingleton&) = delete;MySingleton& operator=(const MySingleton&) = delete;static MySingleton* instance;static std::once_flag initInstanceFlag;static void initSingleton(){instance = new MySingleton;}
};MySingleton* MySingleton::instance = nullptr;
std::once_flag MySingleton::initInstanceFlag;std::chrono::duration<double> getTime(){auto begin = std::chrono::system_clock::now();for (size_t i = 0; i <= tenMill; ++i){MySingleton::getInstance();}return std::chrono::system_clock::now() - begin;};
}int test_call_once_3()
{auto fut1 = std::async(std::launch::async, getTime);auto fut2 = std::async(std::launch::async, getTime);auto fut3 = std::async(std::launch::async, getTime);auto fut4 = std::async(std::launch::async, getTime);auto total = fut1.get() + fut2.get() + fut3.get() + fut4.get();std::cout << total.count() << std::endl;return 0;
}} // namespace call_once_
GitHub: https://github.com/fengbingchun/Messy_Test
相关文章:

Solaris 上网配置
2019独角兽企业重金招聘Python工程师标准>>> 早上装solaris10系统的时候,没选默认,选了desk-session模式安装。全英文无界面安装,中间还跑出几个乱码。 靠着随便选随便F2,终于安装完了。 就在那设完分辨率后࿰…

Configure,Makefile.am, Makefile.in, Makefile文件之间关系
为什么80%的码农都做不了架构师?>>> 1.autoscan (autoconf): 扫描源代码以搜寻普通的可移植性问题,比如检查编译器,库,头文件等,生成文件configure.scan,它是configure.ac的一个雏形。 your source files…

这款耳机一点不输千元级的AirPods
你如果问我:生活中你觉得必不可少的一件电子产品是什么?那么我会毫不犹豫的回答你:是耳机!出门忘带耳机是绝对不能忍听不听没关系,但是有它比较安心我觉得生活中不仅是我很多人都对耳机有一种依赖因为很多人都喜欢音乐…
CUDA Samples: Image Process: BGR to Gray
在图像处理中,颜色变换BGR到Gray,常见的一般有两种计算方式,一种是基于浮点数计算,一种是基于性能优化的通过移位的整数计算。浮点数计算公式为: gray 0.1140 * B 0.5870 * G 0.2989 * R;整数计算公式为࿱…

CYQ.Data 数据框架系列索引
2019独角兽企业重金招聘Python工程师标准>>> 索引基础导航: 1:下载地址:http://www.cyqdata.com/download/article-detail-426 2:入门教程:http://www.cyqdata.com/cyqdata/article-cate-33 3:购…

Tesseract 3 语言数据的训练方法
OCR,光学字符识别 光学字符识别(OCR,Optical Character Recognition)是指对文本资料进行扫描,然后对图像文件进行分析处理,获取文字及版面信息的过程。OCR技术非常专业,一般多是印刷、打印行业的从业人员使用,可以快速的将纸质资料…

Windows C++中__declspec(dllexport)的使用
__declspec是Microsoft VC中专用的关键字,它配合着一些属性可以对标准C/C进行扩充。__declspec关键字应该出现在声明的前面。 __declspec(dllexport)用于Windows中的动态库中,声明导出函数、类、对象等供外面调用,省略给出.def文件。即将函数…

图灵奖得主LeCun力推无监督学习:要重视基于能量的学习方法
作者 | Tiernan Ray译者 | 夕颜出品 | AI科技大本营(ID:rgznai100)导语:图灵奖得主深度学习大牛 Yann LeCun 表示,人工智能的下一个发展方向可能是放弃深度学习的所有概率技巧,转而掌握一系列转移能量值的方法。据说&a…

html5小游戏Untangle
2019独角兽企业重金招聘Python工程师标准>>> 今天介绍一个HTML5的小游戏,让大家体验到HTML5带来的乐趣。这个小游戏很简单,只要用鼠标拖动 蓝点,让图上的所有线都不相交,游戏时间就会停止,是动用大家头脑的…

【VMCloud云平台】SCCM(四)域内推送代理
继上一篇云平台完成SCCM部署篇之后,SCCM篇正式开始,今天将开始介绍SCCM为域内机器推送代理(紫色为完成实施,红色为实施中): 1、 点击站点: 2、 右键属性,点击客户端安装设置&#…
Python实现决策树(Decision Tree)分类
关于决策树的简介可以参考: http://blog.csdn.net/fengbingchun/article/details/78880934在 https://machinelearningmastery.com/implement-decision-tree-algorithm-scratch-python/ 中给出了CART(Classification and Regression Trees,分类回归树算法,简称CART…

顶尖技术专家严选,15场前沿论坛思辨,2019中国大数据技术大会邀您共赴
扫码了解2019中国大数据技术大会(https://t.csdnimg.cn/IaHb)更多详情。2019中国大数据技术大会(BDTC 2019)将于12月5日-7日在北京长城饭店举办,本届大会将聚焦智能时代,大数据技术的发展曲线以及大数据与社…

jQuery 加法计算 使用+号即强转类型
1 var value1 $("#txt1").val(); 2 var value2 $("#txt2").val(); 3 //数值前添加号 number加号和数值加号需要用空格隔开 即实现加法运算 4 $("#txt3").val(value1 value2); 转载于:https://www.cnblogs.com/xiemin-minmin/p/11026784.…

Android Volley 库通过网络获取 JSON 数据
本文内容 什么是 Volley 库 Volley 能做什么 Volley 架构 环境 演示 Volley 库通过网络获取 JSON 数据 参考资料 Android 关于网络操作一般都会介绍 HttpClient 以及 HttpConnection 这两个包。前者是 Apache 开源库,后者是 Android 自带 API。企业级应用࿰…

哪些开发问题最让程序员“头秃”?我们分析了Stack Overflow的11000个问题
作者 | Nick Roberts编译 | AI科技大本营(ID:rgznai100)自 2008 年成立以来,Stack Overflow 一直在拯救所有类型的开发人员。自那时以来,开发人员提出了数百万个关于开发领域的问题。但是,迫使开发者转向 Stack Overfl…
OpenCV3.3中决策树(Decision Tree)接口简介及使用
OpenCV 3.3中给出了决策树Decision Tres算法的实现,即cv::ml::DTrees类,此类的声明在include/opencv2/ml.hpp文件中,实现在modules/ml/src/tree.cpp文件中。其中:(1)、cv::ml::DTrees类:继承自cv::ml::StateModel&…

ARM 寄存器 和 工作模式了解
一. ARM 工作模式 1. ARM7,ARM9,ARM11,处理器有 7 种工作模式;Cortex-A 多了一个监视模式(Monitor) 2. 用户模式:非特权模式,大部分任务执行在这种模式,它运行在操作系…

英文版PDF不能显示中文PDF文件的解决方法
首先,PDF如果是英文版本的话,先装一个与之对应的PDF中文包。装上之后要检查的两项:1、PDF本身打开Adobe pdf选择“edit”"Preference""Internet"将"internet"下的三个勾全部勾上"OK"2、IE设置打开IE…

Linux下__attribute__((visibility (default)))的使用
在Linux下动态库(.so)中,通过GCC的C visibility属性可以控制共享文件导出符号。在GCC 4.0及以上版本中,有个visibility属性,可见属性可以应用到函数、变量、模板以及C类。 限制符号可见性的原因:从动态库中尽可能少地输出符号是一…

java web学习项目20套源码完整版
java web学习项目20套源码完整版 自己收集的各行各业的都有,这一套源码吃遍所有作业项目! 1、BBS论坛系统(jspsql)2、ERP管理系统(jspservlet)3、OA办公自动化管理系统(Struts1.2Hibernate3.0Spring2DWR)4、…

360金融携手上海交大共建AI实验室,开启人才战略新布局
10月16日,上海交通大学计算机科学系—360金融人工智能联合实验室成立仪式在上海交通大学闵行校区举行,联合实验室致力于AI技术在新金融领域的应用探索。成立仪式上,360金融CEO吴海生宣布了“未来科学家”计划,这是360金融在人工智…
wxWidgets刚開始学习的人导引(3)——wxWidgets应用程序初体验
wxWidgets刚開始学习的人导引全文件夹 PDF版及附件下载1 前言2 下载、安装wxWidgets3 wxWidgets应用程序初体验4 wxWidgets学习资料及利用方法指导5 用wxSmith进行可视化设计附:学习材料清单3 wxWidgets应用程序初体验本文中全部的体验,在Code::Blocks…

C++中extern的使用
在C中,extern主要有两个作用:(1)、extern声明一个变量或函数;(2)、extern与”C”一起连用,用于链接指定。关于extern “C”的使用可以参考: http://blog.csdn.net/fengbingchun/article/details/78634831 ,…

Python识别文字,实现看图说话 | CSDN博文精选
作者 | 张小腿来源 | CSDN博客现在写文件很多网站都不让复制了,所以每次都是截图然后发到QQ上然后用手机QQ的文字识别再发回电脑。感觉有点小麻烦了,所以想自己写一个小软件方便方便自己,就有了这篇了:首先语言是Python࿰…

Oracle Hints具体解释
在向大家具体介绍Oracle Hints之前,首先让大家了解下Oracle Hints是什么,然后全面介绍Oracle Hints,希望对大家实用。基于代价的优化器是非常聪明的,在绝大多数情况下它会选择正确的优化器,减轻了DBA的负担。但有时它也…
主成分分析(PCA)简介
主成分分析(Principal Components Analysis, PCA)是一个简单的机器学习算法,可以通过基础的线性代数知识推导。假设在Rn空间中我们有m个点{x(1),…,x(m)},我们希望对这些点进行有损压缩。有损压缩表示我们使用更少的内存,但损失一些精度去存储…

01-HTML基础与进阶-day6-录像281
04css选择器.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Document</title><style type"text/css">/* p div 标签选择器*/p {color: red; /* k:v color表示样式属性 颜…

百度CTO王海峰:深度学习如何大规模产业化?
编者按:10月17日-19日,2019年中国计算机大会(CNCC2019)在苏州举办。百度首席技术官王海峰在会上发表题为《深度学习平台支撑产业智能化》的演讲,分享了百度关于深度学习技术推动人工智能发展及产业化应用的思考。以下为…

Kali Linux***测试
Kali Linux***测试实战 第一章http://drops.wooyun.org/tips/826 1.1 Kali Linux简介如果您之前使用过或者了解BackTrack系列Linux的话,那么我只需要简单的说,Kali是BackTrack的升级换代产品,从Kali开始,BackTrack将成为历史。如果…

一站式解决:隐马尔可夫模型(HMM)全过程推导及实现
作者 | 永远在你身后转载自知乎用户永远在你身后【导读】隐马尔可夫模型(Hidden Markov Model,HMM)是关于时许的概率模型,是一个生成模型,描述由一个隐藏的马尔科夫链随机生成不可观测的状态序列,每个状态生…