6-11 std atomic續談、std async深入談

一:原子操作std::atomic續談

一般atomic原子操作,針對++,–,+=,&=,|=,^=是支持的。

std::atomic<int> g_mycout = 0;//這是個原子整型類型變量;可以向使用整型變量一樣使用
void mythread()
{
	for(int i = 0;i<1000000;i++)
	{
		g_mycout++;	//對應的操作就是原子操作,不會被打斷;
		g_mycout +=1;
		g_mycout = g_mycout + 1;//結果不對
	}
}
void main()
{
	thread myobj1(mythread);
	thread myobj2(mythread);
	myobj1.join();
	myobj2.join();
	cout<<"兩個線程都執行完畢,最終的g_mycout的結果是"<<g_mycout<<endl;

}

二:std::async深入談

2.1、std::async參數詳述,async用來創建一個異步任務;
參數std::launch::deferred[延遲調用],以及std::launch::async[強制創建一個線程]
std::thread()如果系統資源緊張,那麼可能創建線程就會失敗,那麼執行std::thread()時整個程序可能崩潰。
std::async()我們一般不叫創建線程(解釋async能夠創建線程),我們一般叫它創建一個異步任務。
std::async和std::thread最明顯的不同,就是async有時候並不創建新線程。
a、如果你用std::launch::deferred來調用 async會怎麼樣?
std::launch::deferred延遲調用,並且不創建新線程,延遲到future對象調用.get()或者.wait的時候才執行mythread(),如果沒有調用get()或wait,那麼這個mythread()不會執行。
b、std::launch::async:強制這個異步任務在新線程上執行,這意味着,系統必須要給我創建出新線程來運行mythread();
c、std::launch::async|std::launch::deferred
這裏這個|:意味着調用async的行爲可能是”創建新線程並立即執行“或者沒有創建新線程並且延遲到調用result.get()纔開始執行任務入口函數,兩者居其一;
d、我們不帶額外參數;只給async函數一個入口函數名;
默認值應該是std::launch::async|std::launch::deferred;和c效果完全一致。
換句話說:系統會自行決定是異步(創建新線程)還是同步(不創建新線程)方式運行。

自行決定是啥意思?系統如何決定是異步(創建新線程)還是同步(不創建新線程)方式運行
2.2、std::async和std::thread的區別
std::thread創建線程,如果系統資源緊張,創建線程失敗,那麼整個程序就會報異常崩潰(有脾氣)

int mythread(){return 1;}
std::thread mytobj(mythread);
myobj.join();

std::thread創建線程的方式,如果線程返回值,你想拿到這個值也不容易;
std::async創建異步任務。可能創建也可能不創建線程。並且async調用方法很容易拿到線程的返回值;
由於系統資源限制:
1、如果用std::thread創建的線程太多,則可能創建失敗,系統報告異常,崩潰。
2、如果用std::async,一般就不會報異常不會崩潰,因爲如果系統資源緊張導致無法創建新線程的時候,std::async這種不加額外參數的調用就不會創建新線程。而是後續誰調用了result.get()來請求結果,那麼這個異步任務mythread就運行在執行這條get()語句所在的線程上。
如果你強制std::async一定要創建新線程,那麼就必須使用std::launch::async。承受的代價就是系統資源緊張時,程序崩潰。
3、經驗:一個程序裏,線程數量不宜超過100-200,時間片。
2.3、std::async不確定性問題的解決
不加額外參數的std::async調用,讓系統自行決定 是否創建新線程。
問題焦點在於std::future result = std::async(mythread); //寫法
這個異步任務到底有沒有被推遲執行,(std::launch::async還是std::launch::deferred)
std::future對象的wait_for函數


void main()
{
	cout<<"main start"<<"threadid ="<<std::this_thread::get_id()<<endl;
	std::future<int> result = std::async(mythread);
	std::future_status status = result.wait_for(std::chrono::seconds(0));
	if(status == std::future_status::deferred)
	{
		//線程被延遲執行了(系統資源緊張了,它給我採用std::launch::deferred策略了)
		cout<<result.get()<<endl;
	}
	if (status == std::future_status::timeout)
	{
		//超時線程還沒執行完
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章