2018-11-22 std::thread(c++)傻瓜教程

新建多線程工程

  1. 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’未定義的引用
  1. 包括頭文件#include<thread>
  2. 新建線程
    使用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的使用)

  1. 定義:
    unique_lock中的unique表示獨(dú)占所有權(quán)。
    unique_lock獨(dú)占的是mutex對(duì)象,就是對(duì)mutex鎖的獨(dú)占。
  2. 用法:
    (1)新建一個(gè)unique_lock 對(duì)象
    (2)給對(duì)象傳入一個(gè)std::mutex 對(duì)象作為參數(shù);
    std::mutex mymutex;
    unique_lock lock(mymutex);
  3. 解鎖
    因此加鎖時(shí)新建一個(gè)對(duì)象lockunique_lock lock(mymutex);,而這個(gè)對(duì)象生命周期結(jié)束后自動(dòng)解鎖。
  4. 參考代碼
#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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容