
- 自己用代碼創(chuàng)建的其他線程
- 需要從一個(gè)
函數(shù)開始運(yùn)行- 當(dāng)這個(gè)
函數(shù)運(yùn)行完畢的時(shí)候- 代表這個(gè)線程
運(yùn)行結(jié)束
什么是多線程
不是一條線執(zhí)行,而是多條線,可以同時(shí)干多個(gè)事,即使一條線被堵住了,另一條也可以順利執(zhí)行

主線程應(yīng)該做的是等待子線程執(zhí)行完畢后,自己才能最終退出
如果想讓子線程不被OS強(qiáng)行終止
需要讓
主線程一直保持運(yùn)行,不要讓主線程運(yùn)行完畢即可
thread類和join()函數(shù)
- thread類是用來構(gòu)建
子線程對(duì)象的 - join()函數(shù)是用來
阻塞主線程,讓主線程等待子線程執(zhí)行完畢的函數(shù)
主線程阻塞到
join()這里等待go()執(zhí)行完,當(dāng)子線程執(zhí)行完畢(然后子線程和主線程匯合),這個(gè)join()就會(huì)執(zhí)行完畢,主線程就可以繼續(xù)向下執(zhí)行。
如果沒有join()函數(shù)
沒有join()函數(shù)
就會(huì)發(fā)生異常
異常
如果有join()函數(shù)
有join()函數(shù)
就可以順利執(zhí)行
順利執(zhí)行
detach()的使用
detach()是可以讓主線程和子線程分離
- 當(dāng)調(diào)用了detach()之后,與主線程關(guān)聯(lián)的thread對(duì)象就會(huì)失去與這個(gè)主線程的關(guān)聯(lián)
- 此時(shí)這個(gè)子線程會(huì)駐留在
后臺(tái)運(yùn)行(主線程和這個(gè)子線程失去聯(lián)系)
如果主線程提前退出了,子線程就會(huì)被C++運(yùn)行時(shí)庫接管,當(dāng)子線程執(zhí)行完的時(shí)候,運(yùn)行時(shí)庫會(huì)清理這個(gè)子線程的相關(guān)資源
這個(gè)線程一般被稱為
守護(hù)進(jìn)程
detach()使用結(jié)果
detach()導(dǎo)致輸出的格式是亂的,隨機(jī)的,detach()后線程是不受控制的
detach()使用結(jié)果
什么是joinable()
如果一直沒有調(diào)用過join()和detach(),那么joinable()就是true
如果調(diào)用過,那么joinable()就是false
因?yàn)閖oin()和detach()不能同時(shí)調(diào)用,并且只能調(diào)用一次
其他創(chuàng)建線程的手法
之前的創(chuàng)建手法回顧
thread myobj(go)
這個(gè)go()是一個(gè)函數(shù),也是一個(gè)可調(diào)用對(duì)象
類(或者說是類對(duì)象)也可以作為一個(gè)可調(diào)用對(duì)象
如果使用detach()
可以看到析構(gòu)函數(shù)只調(diào)用了一個(gè),這個(gè)析構(gòu)函數(shù)是析構(gòu)主線程的那個(gè)可調(diào)用對(duì)象的,因?yàn)樽泳€程那個(gè)還沒執(zhí)行完(藍(lán)色箭頭)
使用detach()
如果使用join()
第一個(gè)析構(gòu)函數(shù)是子線程的
第二個(gè)析構(gòu)函數(shù)是主線程的
使用join()
“復(fù)制”還是“引用 or 指針”
如果我們用的是join(),那么用引用還是值傳遞都可以
如果用的是detach(),當(dāng)主線程退出的時(shí)候,myi變量會(huì)被系統(tǒng)自動(dòng)銷毀,那么這個(gè)時(shí)候子線程中就沒有東西可以執(zhí)行了,就會(huì)有異常。
需要注意的是這里的可調(diào)用對(duì)象
ta進(jìn)入子線程后是直接復(fù)制了一份,所以拷貝構(gòu)造函數(shù)被執(zhí)行了。
- 所以說還是用join穩(wěn)啊。
lambda表達(dá)式
使用join()
join()
使用detach()
detach()
小結(jié)
可以用函數(shù)、類對(duì)象、lambda表達(dá)式創(chuàng)建線程,作為線程的入口
博客示例代碼
- thread和join()
#include <iostream>
#include <thread>
using namespace std;
void go()
{
cout << "子線程開始執(zhí)行了!" << endl;
cout << "子線程運(yùn)行完畢了!" << endl;
}
int main()
{
thread myObj(go);
myObj.join();
cout << "主線程開始執(zhí)行了!" << endl;
return 0;
}
- detach()
#include <iostream>
#include <thread>
using namespace std;
void go()
{
cout << "子線程開始執(zhí)行了!" << endl;
cout << "子線程運(yùn)行完畢了1" << endl;
cout << "子線程運(yùn)行完畢了2" << endl;
cout << "子線程運(yùn)行完畢了3" << endl;
cout << "子線程運(yùn)行完畢了4" << endl;
cout << "子線程運(yùn)行完畢了5" << endl;
cout << "子線程運(yùn)行完畢了6" << endl;
cout << "子線程運(yùn)行完畢了7" << endl;
cout << "子線程運(yùn)行完畢了8" << endl;
cout << "子線程運(yùn)行完畢了9" << endl;
cout << "子線程運(yùn)行完畢了10" << endl;
}
int main()
{
thread myObj(go);
// myObj.join();
myObj.detach();
cout << "fucking bitch 1" << endl;
cout << "fucking bitch 2" << endl;
cout << "fucking bitch 3" << endl;
cout << "fucking bitch 4" << endl;
cout << "fucking bitch 5" << endl;
cout << "fucking bitch 6" << endl;
cout << "fucking bitch 7" << endl;
cout << "fucking bitch 8" << endl;
cout << "fucking bitch 9" << endl;
cout << "fucking bitch 10" << endl;
return 0;
}
- 類對(duì)象
#include <iostream>
#include <thread>
using namespace std;
class TA
{
public:
int m_i;
TA(int i) : m_i(i) { cout << "TA()構(gòu)造函數(shù)被執(zhí)行" << endl; }
TA(const TA& ta) : m_i(ta.m_i) { cout << "TA()拷貝構(gòu)造函數(shù)被執(zhí)行" << endl; }
~TA() { cout << "~TA()析構(gòu)函數(shù)被執(zhí)行" << endl; }
void operator() ()
{
cout << "m_i1的值為:" << m_i << endl;
cout << "m_i2的值為:" << m_i << endl;
cout << "m_i3的值為:" << m_i << endl;
cout << "m_i4的值為:" << m_i << endl;
cout << "m_i5的值為:" << m_i << endl;
cout << "m_i6的值為:" << m_i << endl;
cout << "m_i7的值為:" << m_i << endl;
cout << "m_i8的值為:" << m_i << endl;
}
};
int main()
{
int myi = 6;
TA ta(myi);
thread myObj(ta);
myObj.join();
//myObj.detach();
cout << "fucking bitch 1" << endl;
cout << "fucking bitch 2" << endl;
cout << "fucking bitch 3" << endl;
cout << "fucking bitch 4" << endl;
cout << "fucking bitch 5" << endl;
cout << "fucking bitch 6" << endl;
cout << "fucking bitch 7" << endl;
cout << "fucking bitch 8" << endl;
cout << "fucking bitch 9" << endl;
cout << "fucking bitch 10" << endl;
return 0;
}
- lambda表達(dá)式
#include <iostream>
#include <thread>
using namespace std;
int main()
{
auto mylambdathread = []
{
cout << "我的線程開始執(zhí)行了" << endl;
cout << "我的線程執(zhí)行結(jié)束了" << endl;
cout << "我的線程執(zhí)行結(jié)束了" << endl;
cout << "我的線程執(zhí)行結(jié)束了" << endl;
cout << "我的線程執(zhí)行結(jié)束了" << endl;
};
thread myobj(mylambdathread);
// myobj.join();
myobj.detach();
cout << "Fucking bitch" << endl;
return 0;
}








