C++11 std::call_once函数和std::once_flag结构体变量


  需要的变量(variable)容器(container)只需要初始化一次,以容器(containter)为例子,可能只是需要向其中注入一次元素. C++11开始标准库提供了std::call_once()和std::once_flag的组合可以帮助我们做到这一点. 在多线程编程中,有一个常见的情景是某个任务仅仅须要运行一次

//Demo1 
1
#include <iostream> 2 #include <thread> 3 #include <mutex> 4 #include <vector> 5 6 std::vector<int> vec; 7 std::mutex mutex; 8 std::once_flag flag; 9 10 static int val = 0; 11 12 void initialized_vec(std::vector<int>& vec) 13 { 14 for (int i = 0; i < 10; ++i) { 15 vec.push_back(val++); 16 } 17 } 18 19 void print_vec() 20 { 21 std::call_once(flag, initialized_vec, vec); 22 std::lock_guard<std::mutex> auto_lock(mutex); 23 for (const int& number : vec) { 24 std::cout << number << " "; 25 } 26 std::cout << std::endl; 27 } 28 29 int main() 30 { 31 std::thread threads[5]; 32 for (int i = 0; i < 5; ++i) { 33 threads[i] = std::thread(print_vec); 34 } 35 36 for (std::thread& ref_thread : threads) { 37 ref_thread.join(); 38 } 39 40 return 0; 41 }
//Demo2 
1
#include <iostream> 2 #include <thread> 3 #include <mutex> 4 5 #include "Singleton.h" 6 7 8 void function(int& number) 9 { 10 number = 20; 11 } 12 13 int main() 14 { 15 int number{ 0 }; 16 std::once_flag onceFlag; 17 18 std::call_once(onceFlag, function, number); 19 std::cout << number << std::endl; //20! ref number 20 21 return 0; 22 }

  其中头文件#include<mutex>即可使用。下面为头文件中的声明。能够看到once_flag是不同意改动的。拷贝构造函数和operator=函数都声明为delete,这样防止程序猿乱用。另外,call_once也是非常easy的。仅仅要传进一个once_flag。回调函数,和參数列表就能够了。

 1 struct once_flag
 2 {
 3     constexpr once_flag() noexcept;
 4     once_flag(const once_flag&) = delete;
 5     once_flag& operator=(const once_flag&) = delete;
 6 };
 7 template<class Callable, class ...Args>
 8   void call_once(once_flag& flag, Callable&& func, Args&&... args);
 9 
10 }  // std

参考:C++11于once_flag,call_once分析的实现


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM