试用std::once_flag和std::call_once保护数据只一次初始化
2022/1/10 23:37:46
本文主要是介绍试用std::once_flag和std::call_once保护数据只一次初始化,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1、once_flag源码
struct once_flag { private: typedef __gthread_once_t __native_type; __native_type _M_once = __GTHREAD_ONCE_INIT; public: /// Constructor constexpr once_flag() noexcept = default; /// Deleted copy constructor once_flag(const once_flag&) = delete; /// Deleted assignment operator once_flag& operator=(const once_flag&) = delete; template<typename _Callable, typename... _Args> friend void call_once(once_flag& __once, _Callable&& __f, _Args&&... __args); };
2、call_once源码
template<typename _Callable, typename... _Args> void call_once(once_flag& __once, _Callable&& __f, _Args&&... __args) { // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2442. call_once() shouldn't DECAY_COPY() auto __callable = [&] { std::__invoke(std::forward<_Callable>(__f), std::forward<_Args>(__args)...); }; __once_callable = std::__addressof(__callable); __once_call = []{ (*(decltype(__callable)*)__once_callable)(); }; int __e = __gthread_once(&__once._M_once, &__once_proxy); if (__e) __throw_system_error(__e); }
3、试用
#include <iostream> #include <mutex> #include <memory> #include <thread> using namespace std; struct some_res { some_res() { cout << std::this_thread::get_id() << " : " << __func__ << " : " << "start init" << endl; } private: // big-data }; std::shared_ptr<some_res> res_ptr; std::once_flag res_flag; void foo() { std::call_once(res_flag, [](){ cout << std::this_thread::get_id() << " : " << "start init" << endl; res_ptr = make_shared<some_res>(); cout << std::this_thread::get_id() << " : " << "end init" << endl; }); } void test_static_init() { static some_res res; } int main(int argc, char const *argv[]) { std::thread t1(foo); std::thread t2(foo); t1.join(); t2.join(); // C++11 内存模型 保证初始化只能在一个线程中执行 std::thread t3(test_static_init); std::thread t4(test_static_init); t3.join(); t4.join(); return 0; }
执行结果:
0x800083f90 : start init 0x800083f90 : some_res : start init 0x800083f90 : end init 0x8000841e0 : some_res : start init
这篇关于试用std::once_flag和std::call_once保护数据只一次初始化的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-08测试人员在 Scrum 中的角色是什么?
- 2024-07-07Dify + TiDB Vector,快速构建你的AI Agent
- 2024-07-06有没有什么开源的py项目可以对图像进行分类-icode9专业技术文章分享
- 2024-07-05feign默认connecttimeout和readtimeout是多少-icode9专业技术文章分享
- 2024-07-05idea控制台,日志太多,导致部分想看得日志被刷走 搜不到-icode9专业技术文章分享
- 2024-07-05The server selected protocol version Tls10 is not accepted by client preferences [TLs12]-icode9专业技术文章分享
- 2024-07-05怎么清理项目缓存-icode9专业技术文章分享
- 2024-07-04安装 Eyoucms详细图文教程-icode9专业技术文章分享
- 2024-07-04ueditor 复制文章时,图片的链接是一个下载图片地址,该如何处理?-icode9专业技术文章分享
- 2024-07-04怎样判断host有没有对wordpress有缓存呢-icode9专业技术文章分享