新建多線程工程
- cmake文件 加入編譯選項(xiàng)c11和多線程
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11 -pthread -g -march=native")
很重要??!不然會(huì)爆出錯(cuò)誤
在函數(shù)‘std::thread::thread<void (*)()>(void (*&&)())’中:
/usr/include/c++/5/thread:137:對(duì)‘pthread_create’未定義的引用
- 包括頭文件
#include<thread> - 新建線程
使用thread 線程名來(lái)新建線程
#include <iostream>
#include<thread>
#include<unistd.h>
using namespace std;
void sayHello() {
while (1) {
sleep(1);
cout << endl << "hello" << endl;
}
}
void sayWorld() {
while (1) {
sleep(1);
cout << endl << "world" << endl;
}
}
int main() {
thread threadHello(&sayHello);
thread threadWorld(&sayWorld);
threadHello.join();
threadWorld.join();
return 0;
}
代碼解析:
- c++在新建一個(gè)線程
thread threadHello(&sayHello);,在新建的過(guò)程會(huì)自動(dòng)調(diào)用線程內(nèi)容,所以新建的位置需要注意。 -
threadHello.join();的意思是外在的線程(一般為主線程)等待*this線程(這里就是threadHello線程)的完成,阻塞外在的線程。 - thread其他方法
.detach(),調(diào)用之后,目標(biāo)線程就成為了守護(hù)線程,駐留后臺(tái)運(yùn)行,與之關(guān)聯(lián)的std::thread對(duì)象失去對(duì)目標(biāo)線程的關(guān)聯(lián),無(wú)法再通過(guò)std::thread對(duì)象取得該線程的控制權(quán)。當(dāng)線程主函數(shù)執(zhí)行完之后,線程就結(jié)束了,運(yùn)行時(shí)庫(kù)負(fù)責(zé)清理與該線程相關(guān)的資源。
當(dāng)一個(gè)thread對(duì)象到達(dá)生命期終點(diǎn)而關(guān)聯(lián)線程還沒(méi)有結(jié)束時(shí),則thread對(duì)象取消與線程之間的關(guān)聯(lián),目標(biāo)線程線程則變?yōu)榉蛛x線程繼續(xù)運(yùn)行。
注意:在主線程未執(zhí)行完前并沒(méi)有銷(xiāo)毀,仍會(huì)繼續(xù)執(zhí)行。 - 另:若子線程不寫(xiě)
join阻塞主線程或detach后臺(tái)運(yùn)行,不管子線程是否被執(zhí)行完畢。都會(huì)爆出warning:terminate called without an active exception
這是指就是子線程還在運(yùn)行,主進(jìn)程就退出導(dǎo)致了該錯(cuò)誤。即使你認(rèn)為子線程已經(jīng)結(jié)束,但系統(tǒng)沒(méi)有通過(guò)join之類(lèi)的阻塞解除之類(lèi)的方法判斷,都會(huì)爆出這個(gè)warning。
線程死鎖方法(unique_lock的使用)
- 定義:
unique_lock中的unique表示獨(dú)占所有權(quán)。
unique_lock獨(dú)占的是mutex對(duì)象,就是對(duì)mutex鎖的獨(dú)占。 - 用法:
(1)新建一個(gè)unique_lock 對(duì)象
(2)給對(duì)象傳入一個(gè)std::mutex對(duì)象作為參數(shù);
std::mutex mymutex;
unique_lock lock(mymutex); - 解鎖
因此加鎖時(shí)新建一個(gè)對(duì)象lockunique_lock lock(mymutex);,而這個(gè)對(duì)象生命周期結(jié)束后自動(dòng)解鎖。 - 參考代碼
#include <iostream>
#include<thread>
#include<unistd.h>
#include<mutex>
using namespace std;
std::mutex mymutex;
void sayHello() {
int k = 0;
unique_lock<mutex> lock(mymutex);
while (k < 2) {
k++;
cout << endl << "hello" << endl;
sleep(2);
}
}
void sayWorld() {
unique_lock<mutex> lock(mymutex);
while (1) {
cout << endl << "world" << endl;
sleep(1);
}
}
int main() {
thread threadHello(&sayHello);
thread threadWorld(&sayWorld);
threadHello.join();
threadWorld.join();
return 0;
}
程序運(yùn)行步驟是這樣的:
首先同時(shí)運(yùn)行threadHello線程和threadWorld線程
先進(jìn)入threadHello線程的sayHello()函數(shù),這個(gè)時(shí)候加了mymutex鎖,另外一個(gè)threadWorld線程進(jìn)入后發(fā)現(xiàn)mymutex鎖沒(méi)有釋放,只能等待。
當(dāng)過(guò)去兩個(gè)循環(huán)(每個(gè)循環(huán)2秒后)threadHello線程結(jié)束,unique_lock lock(mymutex)的生命周期結(jié)束,mymutex鎖釋放,執(zhí)行threadWorld線程,此時(shí)開(kāi)始一直say world。
參考:
https://blog.csdn.net/ktigerhero3/article/details/78249266/
https://zhidao.baidu.com/question/552422613659595372.html