生活随笔
收集整理的這篇文章主要介紹了
c++11 call_once 使用方法
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
call_once是c++11中引入的新特性,用于保證某個(gè)函數(shù)只調(diào)用一次,即使是多線程環(huán)境下,它也可以可靠地完成一次函數(shù)調(diào)用。特別適用于某個(gè)初始化只執(zhí)行一次的場景。
若調(diào)用call_once一切順利,將會翻轉(zhuǎn)once_flag變量的內(nèi)部狀態(tài),再次調(diào)用該函數(shù)時(shí),所對應(yīng)的目標(biāo)函數(shù)不會被執(zhí)行。
若調(diào)用call_once中發(fā)生異常,不會翻轉(zhuǎn)once_flag變量的內(nèi)部狀態(tài),再次調(diào)用該函數(shù)時(shí),目標(biāo)函數(shù)仍然嘗試執(zhí)行。
下面代碼是在win7+vs2015編譯器測試通過,演示了如何使用c++11 中的call_once方法
?
#include "stdafx.h"
#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>//單利模式應(yīng)用
class CSinglton
{
private://(1)私有額構(gòu)造函數(shù)CSinglton() {}//在析構(gòu)函數(shù)中釋放實(shí)例對象~CSinglton(){if (pInstance != NULL){delete pInstance;pInstance = NULL;}}
public://(3)獲得本類實(shí)例的唯一全局訪問點(diǎn)static CSinglton* GetInstance(){//若實(shí)例不存在,則嘗試創(chuàng)建實(shí)例對象if (NULL == pInstance){//call_once object makes sure calling CreateInstance function only one time;//it will be safe without lock;try {std::call_once(m_flag, CreateInstance);}catch (...) {std::cout << "CreateInstance error\n";}}//實(shí)例已經(jīng)存在,直接該實(shí)例對象return pInstance;}static void CreateInstance(){pInstance = new(std::nothrow) CSinglton();//分配失敗,是返回NULL;if (NULL == pInstance){throw std::exception();}}private:static CSinglton* pInstance;//(2)唯一實(shí)例對象static std::once_flag m_flag;
};CSinglton* CSinglton::pInstance = NULL;
//構(gòu)造 once_flag 對象,內(nèi)部狀態(tài)被設(shè)為指示函數(shù)仍未被調(diào)用。
std::once_flag CSinglton::m_flag;//輔助測試代碼
std::mutex g_mutex;
void PrintInstanceAddr()
{std::this_thread::sleep_for(std::chrono::microseconds(1));//get instance CSinglton* pIns = CSinglton::GetInstance();//print instance addrstd::lock_guard<std::mutex> lock(g_mutex);std::cout << pIns << std::endl;
}int main()
{std::thread td[5];//multhread get instance addr;for (int i = 0; i < 5; i++){td[i] = std::thread(PrintInstanceAddr);}for (int i = 0; i < 5; i++){td[i].join();}return 0;
}
運(yùn)行結(jié)果:
0076E778
0076E778
0076E778
0076E778
0076E778
注意:上面的單例模式即直接按下面那樣不加鎖,不用std::call_once調(diào)用,在多線程中會因?yàn)榫€程競爭而導(dǎo)致不正確的結(jié)果出現(xiàn)。
//(3)獲得本類實(shí)例的唯一全局訪問點(diǎn)static CSinglton* GetInstance(){//若實(shí)例不存在,則嘗試創(chuàng)建實(shí)例對象if (NULL == pInstance){try {CreateInstance);}catch (...) {std::cout << "CreateInstance error\n";}}//實(shí)例已經(jīng)存在,直接該實(shí)例對象return pInstance;}
本文轉(zhuǎn)自:https://blog.csdn.net/c_base_jin/article/details/79307262?
參考資料:
http://zh.cppreference.com/w/cpp/thread/call_once
http://www.cplusplus.com/reference/mutex/call_once/?kw=call_once
總結(jié)
以上是生活随笔為你收集整理的c++11 call_once 使用方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。