C++11 call_once和once_flag
阿新 • • 發佈:2022-05-06
call_once
是c++11中引入的新特性,用於保證某個函式只調用一次,即使是多執行緒環境下,它也可以可靠地完成一次函式呼叫。一般配合once_flag
變數。
特別適用於多執行緒時某個初始化只執行一次的場景。
- 若呼叫call_once一切順利,將會翻轉once_flag變數的內部狀態,再次呼叫該函式時,所對應的目標函式不會被執行。
- 若呼叫call_once中發生異常,不會翻轉once_flag變數的內部狀態,再次呼叫該函式時,目標函式仍然嘗試執行。
#include <iostream> #include <thread> #include <mutex> #include <chrono> #include <thread> using namespace std::chrono_literals; std::once_flag flag1, flag2; void simple_do_once() { std::this_thread::sleep_for(2s); std::call_once(flag1, []() { std::cout << "Simple example: called once\n"; }); } void may_throw_function(bool do_throw) { std::this_thread::sleep_for(2s); if (do_throw) { std::cout << "throw: call_once will retry\n"; // this may appear more than once throw std::exception(); } std::cout << "Didn't throw, call_once will not attempt again" << std::endl; // guaranteed once } void do_once(bool do_throw) { try { std::call_once(flag2, may_throw_function, do_throw); } catch (...) { } } int main() { 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(); }