C++11 once_flag与call_once组合,实现函数只调用一次
2019-01-28 20:57
3403 查看
版权声明:转载请注明出处!! https://blog.csdn.net/xucongyoushan/article/details/86500367
once_flag与call_once
头文件
#include <mutex>
once_flag结构
std::once_flag实例的状态,指示所关联的函数尚未被调用。
其构造函数拥有constexpr指定符,以带有静态存储时间段的实例,作为静态初始化阶段的一部分被构造,避免竞争条件和初始化顺序问题。
struct once_flag { constexpr once_flag() noexcept : _Opaque(0){} once_flag(const once_flag&) = delete; once_flag& operator=(const coce_flag&) = delete; void *_Opaque; }
call_once函数模板
在同一std::once_flag对象上,std::call_once调用被序列化。
当且仅当_Fx的调用返回而无异常,std::call_once的调用有效。
若在同一std::once_flag对象上,之前未有过有效的std::call_once调用,参数_Fx(或其副本)如同通过INVOKE(_Fx, _Ax)一样被调用。
如果在同一std::once_flag对象上,之前有过有效的std::call_once,对std::call_once的后续调用直接返回而不执行_Fx。
template<typename _Fn, typename... _Args> inline void call_once(once_flag& _Flag, _Fn&& _Fx, _Args&&... _Ax);
用法
有时对于一类对象,只需初始化一次环境,可以采用类似的封装方式:
#include <mutex> class Module { public: Module() {} ~Module() {} void init() { static std::once_flag once_init; std::call_once(once_init, openLibs); } private: static void openLibs() {} };
错误用法
在上述的openLibs函数中,再次间接通过std::call_once调用自己,会导致栈溢出错误。这是由于未完成一次有效调用,还未改变std::once_flag的状态,仍然造成openLibs被多次调用的情况。
参考文献
C++并发编程实战
相关文章推荐
- C++11中once_flag,call_once实现分析
- [精] C++11中once_flag,call_once实现分析
- C++11中once_flag,call_once实现
- C++11于once_flag,call_once分析的实现
- 函数的调用机制_用递归实现栈(Function call machenism_Recursive calls stimulate stack)
- vb module_FunctionPtr 与FunctionPtr共同实现 CallFromDll callbyAddress 可以调用模块的函数/callbyname
- Unix/Linux fork() 函数一次调用2次返回实现原理(个人理解仅供参考)
- C++11: std::call_once和std::one_flag
- 一次意外的ioctl调用错误—论不同版本内核的ioctl函数实现
- c++11只调用一次的函数
- c++11 call_once用法(多线程时仅初始化一次的完美解决方案)
- 细说在一次中间件开发中如何实现每次业务调用的唯一标识之流水号生成以及应用
- 函数调用是如何在系统中实现的-以C为例
- 2.6版本Linux上替换系统调用函数实现隐藏文件学习
- 函数的调用规则(__cdecl,__stdcall,__fastcall,__pascal)
- 函数调用方式--__thiscall调用方式和__cdecl,__stdcall有什么区别
- C++11 变长模板之函数调用
- 习题3.2:不调用fcntl函数来实现dup2的功能
- pyton设计一个函数,让返回值的调用来回切换,调用一次,返回1,下次调用返回0
- 如何利用c++11的新特性编写类成员线程函数并实现同步