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