線程標(biāo)識(shí)類型是std::thread::id,可以通過(guò)兩種方式進(jìn)行檢索。第一種,可以通過(guò)調(diào)用std::thread對(duì)象的成員函數(shù)get_id()來(lái)直接獲取。如果std::thread對(duì)象沒(méi)有與任何執(zhí)行線程相關(guān)聯(lián),get_id()將返回std::thread::type默認(rèn)構(gòu)造值,這個(gè)值表示“沒(méi)有線程”。第二種,當(dāng)前線程中調(diào)用std::this_thread::get_id()(這個(gè)函數(shù)定義在<thread>頭文件中)也可以獲得線程標(biāo)識(shí)。
std::thread::id對(duì)象可以自由的拷貝和對(duì)比,因?yàn)闃?biāo)識(shí)符就可以復(fù)用。如果兩個(gè)對(duì)象的std::thread::id相等,那它們就是同一個(gè)線程,或者都“沒(méi)有線程”。如果不等,那么就代表了兩個(gè)不同線程,或者一個(gè)有線程,另一沒(méi)有。
線程庫(kù)不會(huì)限制你去檢查線程標(biāo)識(shí)是否一樣,std::thread::id類型對(duì)象提供相當(dāng)豐富的對(duì)比操作;比如,提供為不同的值進(jìn)行排序。這意味著允許程序員將其當(dāng)做為容器的鍵值,做排序,或做其他方式的比較。按默認(rèn)順序比較不同值的std::thread::id,所以這個(gè)行為可預(yù)見的:當(dāng)a<b,b<c時(shí),得a<c,等等。標(biāo)準(zhǔn)庫(kù)也提供std::hash<std::thread::id>容器,所以std::thread::id也可以作為無(wú)序容器的鍵值。
std::thread::id實(shí)例常用作檢測(cè)線程是否需要進(jìn)行一些操作,比如:當(dāng)用線程來(lái)分割一項(xiàng)工作(如清單2.8),主線程可能要做一些與其他線程不同的工作。這種情況下,啟動(dòng)其他線程前,它可以將自己的線程ID通過(guò)std::this_thread::get_id()得到,并進(jìn)行存儲(chǔ)。就是算法核心部分(所有線程都一樣的),每個(gè)線程都要檢查一下,其擁有的線程ID是否與初始線程的ID相同。
std::thread::id master_thread;
void some_core_part_of_algorithm()
{
if(std::this_thread::get_id()==master_thread)
{
do_master_thread_work();
}
do_common_work();
}
另外,當(dāng)前線程的std::thread::id將存儲(chǔ)到一個(gè)數(shù)據(jù)結(jié)構(gòu)中。之后在這個(gè)結(jié)構(gòu)體中對(duì)當(dāng)前線程的ID與存儲(chǔ)的線程ID做對(duì)比,來(lái)決定操作是被“允許”,還是“需要”(permitted/required)。
同樣,作為線程和本地存儲(chǔ)不適配的替代方案,線程ID在容器中可作為鍵值。例如,容器可以存儲(chǔ)其掌控下每個(gè)線程的信息,或在多個(gè)線程中互傳信息。
std::thread::id可以作為一個(gè)線程的通用標(biāo)識(shí)符,當(dāng)標(biāo)識(shí)符只與語(yǔ)義相關(guān)(比如,數(shù)組的索引)時(shí),就需要這個(gè)方案了。也可以使用輸出流(std::cout)來(lái)記錄一個(gè)std::thread::id對(duì)象的值。
std::cout<<std::this_thread::get_id();
具體的輸出結(jié)果是嚴(yán)格依賴于具體實(shí)現(xiàn)的,C++標(biāo)準(zhǔn)的唯一要求就是要保證ID比較結(jié)果相等的線程,必須有相同的輸出。