1. 程式人生 > >c++11多執行緒程式設計(二):joining和detaching 執行緒

c++11多執行緒程式設計(二):joining和detaching 執行緒

Joining執行緒
執行緒一旦啟動,另一個執行緒可以通過呼叫std::thread物件上呼叫join()函式等待這個執行緒執行完畢
std::thread th(funcPtr); 
th.join();

看一個例子

主執行緒啟動10個工作執行緒,啟動完畢後,main函式等待他們執行完畢,joining完所有執行緒後,main函式繼續執行

#include <iostream>  
#include <thread>  
#include <algorithm>  
  
class WorkerThread  
{  
public:  
    void operator()(){  
        std::cout<<"Worker Thread "<<std::this_thread::get_id()<<"is Excecuting"<<std::endl;  
    }  
};  
  
int main(){  
    std::vector<std::thread> threadList;  
    for(int i = 0; i < 10; i++){  
        threadList.push_back(std::thread(WorkerThread()));  
    }  
    // Now wait for all the worker thread to finish i.e.  
    // Call join() function on each of the std::thread object  
    std::cout<<"Wait for all the worker thread to finish"<<std::endl;  
    std::for_each(threadList.begin(), threadList.end(), std::mem_fn(&std::thread::join));  
    std::cout<<"Exiting from Main Thread"<<std::endl;  
      
    return 0;  
} 

Detaching 執行緒
detach一個執行緒,需要在std::thread物件中呼叫std::detach()函式

std::thread th(funcPtr)
th.detach();
呼叫detach()後,std::thread物件不再與實際執行執行緒相關聯
線上程控制代碼上呼叫detach() 和 join()要小心

case1:不要在沒有關聯執行執行緒的std::thread物件上呼叫join() 或 detach() 

std::thread threadObj(WorkerThread());
threadObj.join();
threadObj.join();// It will cause Program to Terminate
當join()函式線上程物件上執行,當join()返回時,std::thread 物件與他沒有關聯執行緒,如果在這樣的物件上再次呼叫join()函式,那麼它將導致程式終止。

類似的,呼叫detach()使std::thread物件沒有連結任何執行緒函式,在這種情況下,在一個std::thread物件上呼叫detach()函式兩次將導致程式終止。

std::thread threadObj(WorkerThread);
threadObj.detach();
threadObj.detach();// It will cause Program to Terminate

因此,在每次呼叫join()或detach()前,需要檢查執行緒是否join-able

std::thread threadObj(WorkerThread())
if(threadObj.joinable()){
	std::cout<<"Detaching Thread"<<std::endl;
	threadObj.detach();
}
if(threadObj.joinable()){
	std::cout<<"Detaching Thread"<<std::endl;
	threadObj.detach();
}

std::thread threadObj2(WorkerThread())
if(threadObj2.joinable()){
	std::cout<<"Joining Thread"<<std::endl;
	threadObj2.join();
}
if(threadObj2.joinable()){
	std::cout<<"Joining Thread"<<std::endl;
	threadObj2.join();
}

case2:不要忘記使用關聯的執行執行緒在std::thread物件上呼叫join或detach

如果std::thread關聯的執行執行緒沒有呼叫join和detach,那麼在物件的析構期,它將終止程式

因為在析構期,它將檢查執行緒是否仍然Join-able,然後終止程式

#include <iostream>
#include <thread>
#include <algorithm>


class WorkerThread
{
public:
    void operator()()
    {
        std::cout << "Worker Thread" << std::endl;
    }
};


int main()
{
    std::thread threadObj((WorkerThread()));
    //如果沒有在std::thread物件上呼叫join或detach,其解構函式將會終止程式
    return 0;
}
類似的,不能忘記在異常情況下呼叫join或detach,