1.在多執行緒環境下,可能會同時創建多個單例對象。
2.在執行時期加載的情況下,可能會創建多個單例對象的副本。
為了解決這些問題,可以使用 C++11 的 std::once_flag 和 std::call_once
在 C++11 中,std::once_flag 和 std::call_once 提供了一种方法,用於在多執行緒環境下保證函數只被執行一次。std::once_flag 可以用於確保多個執行緒之間的同步,以及控制執行某些操作的次數。
以下是 std::once_flag 和 std::call_once 的簡單示例:
#include <iostream>
#include <thread>
#include <mutex>
std::once_flag flag;
void do_something() {
// 保證函數只被執行一次
std::call_once(flag, [](){
std::cout << "This function is called only once." << std::endl;
});
}
int main() {
std::thread t1(do_something);
std::thread t2(do_something);
std::thread t3(do_something);
std::thread t4(do_something);
t1.join();
t2.join();
t3.join();
t4.join();
return 0;
}
在這個示例中,我們創建了 4 個執行緒,每個執行緒都執行 do_something 函數。但是由於 std::call_once 和 std::once_flag 的存在,do_something 函數只會被執行一次。
另一个示例:
std::once_flag 和 std::call_once 可以幫助您在多執行緒環境下保證函數只被呼叫一次。
下面是一個簡單的例子:
#include <iostream>
#include <mutex>
std::once_flag flag;
void do_something()
{
std::call_once(flag, [](){
std::cout << "Doing something" << std::endl;
});
}
int main()
{
do_something();
do_something();
return 0;
}
在上面的代碼中,函數 do_something 將會被呼叫兩次,但是lambda函數將只會被呼叫一次。
如果您想要保證更大的代碼塊只被呼叫一次,可以使用以下方式:
#include <iostream>
#include <mutex>
std::once_flag flag;
void do_something()
{
std::call_once(flag, [](){
std::cout << "Doing something" << std::endl;
// ...
});
}
int main()
{
do_something();
do_something();
return 0;
}
在這種情況下, lambda 函數將只會被呼叫一次,並且所有在 lambda 函數中的代碼也將只被執行一次。