thread 線程使用和解析

多線程是遊戲開發必備知識。無論是操作系統的互斥鎖還是網絡通信的資源管理,多線程併發是永遠要熟練其使用的知識。

例子1:

#include "stdafx.h"
#include<atomic>
#include <thread>
#include <iostream>

std::atomic<int> a(10);

std::atomic_llong total = {0};//定義爲原子操作,保證多線程互斥訪問

void funCount(int)
{
	for (long long i = 0; i <100000000LL; i++)
	{
		total+=i;
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	std::thread t1(funCount,0);//線程創建後由操作系統啓動和運行,具有不可控性
	std::thread t2(funCount,0);
	t1.join();//join的運行依賴於主線程,當主線程退出時會強制關閉依附於它的子線程,並執行資源回收。調用即主線程被掛起等待join入的子線程運行完再執行新的線程,也就是說線程t2屬性的更改,在於t1執行完成之後
	t2.join();//detach的區別在獨立於主線程,與主線程同級,就面臨一個問題:當主線程退出時,要保證detach的線程不在訪問主線程的資源,否則會報錯。
	//t2.detach();

	;

	std::cout<<__FUNCTION__<<":"<<total<<"\t"<<a.is_lock_free()<<std::endl;
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>//確認線程結束,輸入的是120,線程不在對total進行讀取
	total.store(120);

	std::cout<<__FUNCTION__<<":"<<total<<"\t"<<a.is_lock_free()<<std::endl;

	return 0;
}


爲了驗證t2的更改在屬性線程t1執行完成之後,有如下例子:


int _tmain(int argc, _TCHAR* argv[])
{
	std::thread t1(funCount,0);
	std::cout<<__FUNCTION__<<":"<<total<<"\t"<<a.is_lock_free()<<std::endl;
	std::thread t2(funCount,0);
	std::cout<<__FUNCTION__<<":"<<total<<"\t"<<a.is_lock_free()<<std::endl;
	t1.join();
	
	//t2.detach();

	;

	std::cout<<__FUNCTION__<<":"<<total<<"\t"<<a.is_lock_free()<<std::endl;
	t2.detach();
	//total.store(120);//訪問當前值試試,形成互斥
	std::cout<<__FUNCTION__<<":"<<total<<"\t"<<a.is_lock_free()<<std::endl;

	
	std::cout<<__FUNCTION__<<":"<<total<<"\t"<<a.is_lock_free()<<std::endl;

	return 0;
}
因爲t2還處於默認狀態。

什麼是默認狀態:

在任何一個時間點上,線程是可結合的(joinable),或者是分離的(detached)。一個可結合的線程能夠被其他線程收回其資源和殺死;在被其他線程回收之前,它的存儲器資源(如棧)是不釋放的。相反,一個分離的線程是不能被其他線程回收或殺死的,它的存儲器資源在它終止時由系統自動釋放。

        線程的分離狀態決定一個線程以什麼樣的方式來終止自己。在默認情況下線程是非分離狀態的,這種情況下,原有的線程等待創建的線程結束。只有當pthread_join()函數返回時,創建的線程纔算終止,才能釋放自己佔用的系統資源。而分離線程不是這樣子的,它沒有被其他的線程所等待,自己運行結束了,線程也就終止了,馬上釋放系統資源。程序員應該根據自己的需要,選擇適當的分離狀態。所以如果我們在創建線程時就知道不需要了解線程的終止狀態,則可以pthread_attr_t結構中的detachstate線程屬性,讓線程以分離狀態啓動。


基於此,如果線程t2實現了睡眠的話,就會明顯出現下面的結果(如果主線程結束的比t2早,而t2仍未結束計算,則可能出現中斷。如下的代碼結束後沒有出現中斷,暫時模擬不出中斷待續)


難道和使用了原子類型有關,不對,只有一個可能就是t1回調和main執行的過程中,它已經結束了。

int _tmain(int argc, _TCHAR* argv[])
{
	std::thread t1(funCount,0);
	
	std::cout<<__FUNCTION__<<":"<<total<<"\t"<<total.is_lock_free()<<std::endl;
	
	std::cout<<__FUNCTION__<<":"<<total<<"\t"<<total.is_lock_free()<<std::endl;
	
	t1.detach();
	
	
	//

	;

	std::cout<<__FUNCTION__<<":"<<total<<"\t"<<total.is_lock_free()<<std::endl;
	
	//total.store(120);//訪問當前值試試,形成互斥
	std::cout<<__FUNCTION__<<":"<<total<<"\t"<<total.is_lock_free()<<std::endl;

	
	std::cout<<__FUNCTION__<<":"<<total<<"\t"<<total.is_lock_free()<<std::endl;
std::thread t2(funCount,0);t2.detach();
	return 0;
}

這樣子創建也沒有出現中斷。。機子性能太好了?絕對不是,應該是某個概念我沒理解對。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章