線程運行的開始和結束
整個進程是否執行完畢的標誌是 主線程是否執行完,如果主線程執行完畢了,就代表整個進程執行完畢了;
此時,一般情況,如果其他子線程還沒有執行完畢,那麼這些子線程也會被操作系統強行終止。
所以,一般情況下,如果大家想保持子線程(自己用代碼創建的線程)的運行狀態,大家就要讓主線程一直保持運行,不要讓主線程運行完畢。(這條規律有例外)
#include <thread>
vodi myprint() //自己創建的線程也要從一個函數開始執行
{
cout << "start thread" << endl;
cout << "end thread" << endl;
}
int main(){
thread myobj(myprint); //thread對象的構造函數接受的是一個可調用對象,
//創建了線程,線程執行起點myprint();
myobj.join(); //說白了,就是阻塞主線程,讓主線程等待子線程執行完畢,然後主線程於
//子線程匯合繼續執行,當子線程執行完畢,join()就執行完畢,主線程繼
//續執行
cout << "good luck" << endl;
return 0;
}
上面代碼,有兩個線程再跑,相當於整個程序的執行有兩條線同時在走,基石一條線被堵住了,另外一條線會繼續執行。
thread:是個標準庫中的類。
join():加入,匯合,說白了就是阻塞主線程,讓主線程等待子線程執行完畢,join()就執行完畢。
通常情況,主線程執行完畢了,但子線程沒執行完,這種程序是不穩定的
一個書寫良好的程序應該是主線程等待子線程執行完畢後才退出。
例外:detach():
傳統多線程程序,主線程要等待子線程執行完畢後,在退出,detach分離,主線程不和子線程匯合,主線程和子線程分別執行自己的,主線程並不影響子線程的執行。
爲什麼引入detach:我們創建了很多子線程,讓主線程逐個等待子線程結束,這種編程方法不太好,所以我們引入detach();一旦detach()之後(不建議較多使用detach),與這個主線程關聯的thread對象就會失去與這個主線程的關聯,此時這個子線程就會駐留在後臺運行
主線程跟該子線程失去聯繫,這個子線程就相當於被C++運行時庫接管了,當這個子線程執行完成後由運行時庫負責清理該線程相關資源(守護線程)
#include <thread>
vodi myprint() //自己創建的線程也要從一個函數開始執行
{
cout << "start thread" << endl;
cout << "end thread" << endl;
}
int main(){
thread myobj(myprint); ;
myobj.detach();
cout << "good luck" << endl;
return 0;
}
一旦調用了detach()就不能在join();
joinable():判讀是否可以成功join()或者detach()的。返回true,或者false(返回true時可以join或者detach,返回false時不行)
#include <thread>
vodi myprint() //自己創建的線程也要從一個函數開始執行
{
cout << "start thread" << endl;
cout << "end thread" << endl;
}
int main(){
thread myobj(myprint);
if(myobj.joinable()){ //true
cout << "joinable() == ture" << endl;
}
myobj.detach();
if(!myobj.joinable()){ //false
cout << "joinable() == false" << endl;
}
cout << "good luck" << endl;
return 0;
}
其他創建線程方法
1、用類對象
疑問:一旦定義detach()那麼,主線程執行結束了,那麼ct對象還在麼?如果不在了,detach的線程怎麼執行?
這個對象不在了,但是detach的對象可以正常執行,因爲這個對象實際上是被複制到線程中去,所以執行完主線程後,ct會被銷燬,但是所複製的TA對象依舊存在。所以你這個TA對象裏沒有引用,沒有指針,就不會有問題。
class CT
{
public:
void operator()() //可調用對象
{
}
};
int main(){
CT ct;
thread myobj(ct);
myobj.join();
}
2、lambda表達式
auto mylambda = [] (){
cout << "lambda" << endl;
}
int main(){
thread myobj(mylambda);
//myobj.join();
myobj.detach();
}