2.線程的創建、結束

程序結束的標誌

一個進程的結束的標誌就是主線程是否執行完畢,當屬線程執行完畢時,意味着整個程序已經結束。這樣我們其他的線程的任務執行可能會被強行的終止。所以如果我們想要保持指現場的正常運行,我們需要主線程的壽命大於等於子進程時候,這樣才能將子進程的任務全部執行完。

當然如果想要讓主線程和其他線程是分離的狀態,也就是說想要讓線程自己去回收自己的資源也不是不可以。這種狀態我們一般稱之爲detach,也就是說,讓主線程的執行和其他的線程的執行是完全獨立分開的,主線程的任務執行不會受到子線程的影響。

主線程需要等待其他線程結束

這個就是第一種方式,主進程在那邊等待子進程的任務結束之後將子進程回收。在這種情況下我們需要使用join函數。

但是如果沒寫這個函數的話。主進程先執行完了,子線程還在這邊沒有執行完畢,這樣程序就會變得不穩定,是不合格的。


//這裏面的傳入的參數,
//其實就是你需要執行在線程裏面的函數的函數名,
//也可以理解是函數指針。
thread mythread(funcptr);
//在主線程裏面調用這個函數之後,
//主線程就會在這裏阻塞,等待子線程程序的結束。
mythread.join();

主線從不需要等待線程結束,線程自己處理

剛纔提到的那種情況有一定的弊端,因爲主線程需要在那邊阻塞。隨着技術的發展,子線程出現了一種與主線重分離執行的技術。這裏面使用的就是detach,分離的技術。對於這個函數之後,主線程不必再等待子線程的執行。主線程可以先執行,結束之後子線程回收自己的資源。

 

thread myth(funcptr);
//一旦執行完detach與主線程關聯的thread的對象
//就會失去與主線程的關聯
//這個子線程就會放到後臺去運行
//這個子線程就相當於被init給接管了
myth.detach();

這兩種方式只允許選擇一種

不允許先選擇detach之後又要選擇join,因爲已經放到後臺的程序是抓不回來的,所以當然會報錯誤。也就是說,如果我們對一個線程進行操作的話。我們需要先判斷一下這個線程具不具備這些條件。 

 

bool able = myth.joinable();
if(able)
{
    cout << "允許 join或者detach " << endl;
}

給線程傳遞參數注意

有一些我們想到現場有執行的函數,需要參數傳遞進去。

如果這個線程和主線程是分離的關係,而我們傳遞進去的參數是引、指針這種指向局部變量地址的變量進去的話。

在主線程被銷燬之後,這些變量的空間會被釋放。這樣子線程所使用的這些變量會失效。

所以說我們傳遞給子線程的這些參數最好都是按值傳遞,原原本本的複製裏面的東西進子線程,這樣子線程的後臺執行的時候纔不會有問題。

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