欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++?std::thread?使用方法

 更新時(shí)間:2023年03月18日 08:55:30   作者:馭鯨·環(huán)球  
這篇文章主要介紹了C++?std::thread?如何使用,C++中的std::thread類提供了一種方便的多線程編程方式,在使用std::thread類時(shí),我們需要注意線程間的同步和通信問題,以確保多個(gè)線程之間的正確協(xié)同工作需要的朋友可以參考下

C++是一種高級編程語言,被廣泛用于開發(fā)高性能、大規(guī)模、復(fù)雜的軟件系統(tǒng)。其中一個(gè)強(qiáng)大的特性就是多線程編程,而std::thread是C++標(biāo)準(zhǔn)庫提供的多線程支持的重要組成部分。

std::thread是一個(gè)輕量級線程類,它允許程序員創(chuàng)建、啟動(dòng)、停止、等待線程。與其他多線程庫不同,std::thread在運(yùn)行時(shí)不需要顯式地創(chuàng)建和銷毀線程,而是通過構(gòu)造和析構(gòu)線程對象來完成這些操作。

一、std::thread的構(gòu)造和析構(gòu)

std::thread的構(gòu)造函數(shù)需要傳入一個(gè)可調(diào)用對象,這個(gè)可調(diào)用對象可以是一個(gè)函數(shù)指針、一個(gè)函數(shù)對象、一個(gè)lambda表達(dá)式或一個(gè)類成員函數(shù)指針。創(chuàng)建線程的方式非常簡單,例如:

void my_func()
{
    // do something
}

std::thread my_thread(my_func); // 使用函數(shù)指針創(chuàng)建線程

線程對象創(chuàng)建后,它的執(zhí)行路徑就已經(jīng)開始了。我們可以通過std::thread對象的join()方法等待線程結(jié)束并阻塞主線程:

std::thread my_thread(my_func);
my_thread.join(); // 阻塞主線程等待子線程結(jié)束

當(dāng)線程對象被銷毀時(shí),它會(huì)自動(dòng)調(diào)用析構(gòu)函數(shù),如果線程沒有被join()或detach(),則程序會(huì)終止并拋出std::terminate異常。

std::thread my_thread(my_func);
// 不調(diào)用join()或detach()
// 當(dāng)my_thread對象離開作用域時(shí)會(huì)拋出std::terminate異常

二、std::thread的成員函數(shù)

std::thread類還有一些非常有用的成員函數(shù),可以幫助我們管理線程的生命周期、獲取線程信息和控制線程行為。

1.join()和detach()
join()方法可以阻塞主線程等待子線程結(jié)束,而detach()方法則將線程對象與底層線程分離,使得線程對象的生命周期不再受限于線程的生命周期。

std::thread my_thread(my_func);
my_thread.detach(); // 分離線程,線程對象的生命周期不再受限于線程的生命周期

2.get_id()

get_id()方法返回線程對象所代表的線程的唯一標(biāo)識(shí)符,這個(gè)標(biāo)識(shí)符可以用來比較不同的線程對象是否代表同一個(gè)線程。

std::thread my_thread1(my_func);
std::thread my_thread2(my_func);
if (my_thread1.get_id() == my_thread2.get_id())
{
    // 不會(huì)執(zhí)行到這里
}

3.hardware_concurrency()
hardware_concurrency()方法返回計(jì)算機(jī)硬件支持的并發(fā)線程數(shù),這個(gè)值通常等于處理器的核心數(shù)。

std::cout << "可用線程數(shù):" << std::thread::hardware_concurrency() << std::endl;

三、線程間的通信

線程間的通信是多線程編程中的一個(gè)重要問題,std::thread類提供了一些機(jī)制來幫助我們實(shí)現(xiàn)線程間的通信和同步。

1.std::atomic
std::atomic是一個(gè)原子類型,它可以保證對該類型的操作是原子的,即不會(huì)被其他線程中斷。std::atomic可以用于實(shí)現(xiàn)線程間的共享變量。

std::atomic<int> counter{0};
void my_func()
{
    counter++;
}

int main()
{
    std::thread t1(my_func);
    std::thread t2(my_func);
    t1.join();
    t2.join();
    std::cout << counter << std::endl; // 輸出2
    return 0;
}

2.std::mutex和std::lock_guard
std::mutex是一個(gè)互斥量,它可以用于實(shí)現(xiàn)線程間的互斥訪問。std::lock_guard是一個(gè)RAII風(fēng)格的互斥量保護(hù)器,它可以在構(gòu)造函數(shù)中獲取互斥量的鎖,在析構(gòu)函數(shù)中釋放互斥量的鎖。

std::atomic<int> counter{0};
void my_func()
{
    counter++;
}

int main()
{
    std::thread t1(my_func);
    std::thread t2(my_func);
    t1.join();
    t2.join();
    std::cout << counter << std::endl; // 輸出2
    return 0;
}

3.std::condition_variable
std::condition_variable是一個(gè)條件變量,它可以用于實(shí)現(xiàn)線程間的同步。std::condition_variable通常與std::unique_lock一起使用,可以實(shí)現(xiàn)線程的等待和喚醒操作。

std::mutex my_mutex;
std::condition_variable my_cv;
bool ready = false;
void my_func()
{
    std::unique_lock<std::mutex> lock(my_mutex); // 獲取互斥量的鎖
    ready = true;
    my_cv.notify_one(); // 喚醒等待中的線程
}

int main()
{
    std::thread t1(my_func);
    std::unique_lock<std::mutex> lock(my_mutex);
    my_cv.wait(lock, []{return ready;}); // 等待線程的喚醒
    t1.join();
    return 0;
}

四、線程的異常處理

多線程程序中的異常處理是一個(gè)復(fù)雜的問題,std::thread類提供了一些機(jī)制來幫助我們處理線程中的異常。

1.try-catch塊
在線程函數(shù)中使用try-catch塊可以捕獲線程中的異常,防止異常影響其他線程和整個(gè)程序。

void my_func()
{
    try
    {
        // do something
    }
    catch (const std::exception& e)
    {
        // 處理異常
    }
}

int main()
{
    std::thread t1(my_func);
    std::thread t2(my_func);
    t1.join();
    t2.join();
    return 0;
}

2.std::terminate
std::terminate是一個(gè)函數(shù),它可以用于終止程序的執(zhí)行。當(dāng)線程中發(fā)生未被捕獲的異常時(shí),程序會(huì)自動(dòng)調(diào)用std::terminate函數(shù)來終止程序的執(zhí)行。

void my_func()
{
    throw std::runtime_error("something went wrong");
}

int main()
{
    std::thread t1(my_func);
    std::thread t2(my_func);
    t1.join();
    t2.join();
    return 0;
}

在上面的代碼中,my_func函數(shù)會(huì)拋出一個(gè)std::runtime_error異常,如果這個(gè)異常沒有被try-catch塊捕獲,程序就會(huì)調(diào)用std::terminate函數(shù)來終止程序的執(zhí)行。

3.std::exception_ptr
std::exception_ptr是一個(gè)類,它可以用于保存線程中發(fā)生的異常。我們可以在主線程中調(diào)用std::exception_ptr::rethrow_exception函數(shù)來重新拋出線程中的異常。

std::exception_ptr my_exception;
void my_func()
{
    try
    {
        // do something
    }
    catch (...)
    {
        my_exception = std::current_exception(); // 保存異常
    }
}

int main()
{
    std::thread t1(my_func);
    std::thread t2(my_func);
    t1.join();
    t2.join();
    if (my_exception)
    {
        try
        {
            std::rethrow_exception(my_exception); // 重新拋出異常
        }
        catch (const std::exception& e)
        {
            // 處理異常
        }
    }
    return 0;
}

在上面的代碼中,my_func函數(shù)會(huì)捕獲任何類型的異常,并將異常保存到my_exception變量中。在主線程中,如果my_exception變量中保存了異常,我們就調(diào)用std::rethrow_exception函數(shù)重新拋出異常,并在catch塊中處理異常。

五、總結(jié)

C++11中的std::thread類是一個(gè)強(qiáng)大的多線程編程工具,它可以幫助我們輕松地創(chuàng)建和管理線程。通過std::thread類,我們可以實(shí)現(xiàn)線程的創(chuàng)建、啟動(dòng)、停止、等待和同步等操作,并可以使用各種機(jī)制來處理線程中的異常和實(shí)現(xiàn)線程間的通信。

在使用std::thread類時(shí),我們需要注意以下幾點(diǎn):

  • 線程函數(shù)必須是可調(diào)用對象,如函數(shù)、函數(shù)指針、函數(shù)對象等。
  • 線程函數(shù)的參數(shù)必須是可拷貝的,否則需要使用std::ref包裝。
  • 線程對象必須在主線程中加入join或detach,否則會(huì)導(dǎo)致程序異常。
  • 線程中發(fā)生的異常需要進(jìn)行處理,否則會(huì)導(dǎo)致程序崩潰。

線程間的通信需要使用std::atomic、std::mutex、std::lock_guard和std::condition_variable等機(jī)制。

std::thread類是一個(gè)非常強(qiáng)大的多線程編程工具,它可以幫助我們實(shí)現(xiàn)各種復(fù)雜的多線程應(yīng)用。熟練掌握std::thread類的使用方法和機(jī)制可以提高我們的多線程編程技能,也可以幫助我們更好地處理線程中的異常和實(shí)現(xiàn)線程間的通信。

最后,還有一些需要注意的點(diǎn):

1.線程安全

多線程編程中一個(gè)非常重要的概念就是線程安全。如果多個(gè)線程同時(shí)訪問同一個(gè)共享資源,可能會(huì)出現(xiàn)數(shù)據(jù)競爭(data race),導(dǎo)致程序出現(xiàn)不可預(yù)期的行為。

為了避免數(shù)據(jù)競爭,我們需要使用線程同步機(jī)制來保護(hù)共享資源。常用的線程同步機(jī)制包括std::mutex、std::lock_guard、std::unique_lock和std::condition_variable等。這些同步機(jī)制可以幫助我們實(shí)現(xiàn)互斥鎖、條件變量等功能,以確保多個(gè)線程之間的正確協(xié)同工作。

2.線程池
線程池(thread pool)是一個(gè)管理一組線程的對象。線程池可以幫助我們管理線程的數(shù)量、復(fù)用線程資源、避免線程的創(chuàng)建和銷毀等操作,從而提高多線程應(yīng)用程序的效率。

C++標(biāo)準(zhǔn)庫中并沒有提供線程池的實(shí)現(xiàn),但是我們可以使用第三方庫或自己編寫代碼來實(shí)現(xiàn)線程池。常用的第三方線程池庫包括Boost.Thread和Intel TBB等。

3.并發(fā)編程模型
并發(fā)編程模型是一種抽象的概念,它描述了多個(gè)任務(wù)之間的交互和協(xié)同工作。常用的并發(fā)編程模型包括消息傳遞模型、共享內(nèi)存模型和數(shù)據(jù)流模型等。

消息傳遞模型(message passing)是指多個(gè)任務(wù)之間通過消息傳遞來進(jìn)行通信和同步。共享內(nèi)存模型(shared memory)是指多個(gè)任務(wù)之間通過共享內(nèi)存來進(jìn)行通信和同步。數(shù)據(jù)流模型(data flow)是指多個(gè)任務(wù)之間通過數(shù)據(jù)流來進(jìn)行通信和同步。

C++中的std::thread類可以用于實(shí)現(xiàn)多個(gè)任務(wù)之間的并發(fā)編程模型。在使用std::thread類時(shí),我們需要考慮線程間的同步和通信問題,以確保多個(gè)線程之間的正確協(xié)同工作。

4.多線程性能優(yōu)化
在進(jìn)行多線程編程時(shí),我們需要考慮多線程性能優(yōu)化問題。常用的多線程性能優(yōu)化方法包括:

(1)避免線程的創(chuàng)建和銷毀。線程的創(chuàng)建和銷毀是比較耗時(shí)的操作,如果頻繁地創(chuàng)建和銷毀線程,會(huì)影響多線程應(yīng)用程序的性能。我們可以使用線程池來復(fù)用線程資源,從而避免線程的創(chuàng)建和銷毀。

(2)減少鎖的使用。鎖是一種線程同步機(jī)制,但是鎖的使用會(huì)影響多線程應(yīng)用程序的性能。如果多個(gè)線程之間訪問同一個(gè)共享資源,可以使用無鎖數(shù)據(jù)結(jié)構(gòu)來避免鎖的使用,從而提高多線程應(yīng)用程序的性能。

(3)避免線程間的頻繁通信。線程間的通信是需要開銷的,如果頻繁地進(jìn)行線程間的通信,會(huì)影響多線程應(yīng)用程序的性能。我們可以考慮將通信的數(shù)據(jù)緩存起來,減少線程間的頻繁通信。

(4)使用本地變量。在多線程編程中,本地變量的訪問不需要鎖,可以提高多線程應(yīng)用程序的性能。如果需要訪問共享資源,可以將共享資源拷貝到本地變量中,從而避免鎖的使用。

(5)使用任務(wù)并行模型。任務(wù)并行模型是一種并發(fā)編程模型,它可以將一個(gè)大任務(wù)劃分為多個(gè)小任務(wù),然后將小任務(wù)分配給多個(gè)線程來并行執(zhí)行。這樣可以提高多線程應(yīng)用程序的性能。

總結(jié):

C++中的std::thread類提供了一種方便的多線程編程方式。在使用std::thread類時(shí),我們需要注意線程間的同步和通信問題,以確保多個(gè)線程之間的正確協(xié)同工作。同時(shí),我們還需要考慮多線程性能優(yōu)化問題,以提高多線程應(yīng)用程序的性能。

除了std::thread類,C++標(biāo)準(zhǔn)庫還提供了一些其他的多線程編程工具,例如std::async、std::future、std::promise等,它們都可以用于實(shí)現(xiàn)多線程編程。在進(jìn)行多線程編程時(shí),我們需要根據(jù)具體的應(yīng)用場景選擇合適的多線程編程工具。

最后,多線程編程是一項(xiàng)非常復(fù)雜的任務(wù),需要有一定的經(jīng)驗(yàn)和技能才能掌握。建議初學(xué)者從簡單的例子開始,逐步深入了解多線程編程的相關(guān)概念和技術(shù)。

到此這篇關(guān)于C++ std::thread 如何使用?的文章就介紹到這了,更多相關(guān)C++ std::thread使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • VC中SDK與MFC的區(qū)別淺析

    VC中SDK與MFC的區(qū)別淺析

    這篇文章主要介紹了VC中SDK與MFC的區(qū)別淺析,需要的朋友可以參考下
    2014-07-07
  • C++實(shí)現(xiàn)圖像目標(biāo)區(qū)裁剪ImageCropping

    C++實(shí)現(xiàn)圖像目標(biāo)區(qū)裁剪ImageCropping

    本文主要介紹了C++實(shí)現(xiàn)圖像目標(biāo)區(qū)裁剪ImageCropping,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • c++自定義sort()函數(shù)的排序方法介紹

    c++自定義sort()函數(shù)的排序方法介紹

    這篇文章主要介紹了c++自定義sort()函數(shù)的排序方法介紹,文章通過圍繞主題展開詳細(xì)的內(nèi)容戒殺,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • C語言中pow函數(shù)使用方法、注意事項(xiàng)以及常見報(bào)錯(cuò)原因

    C語言中pow函數(shù)使用方法、注意事項(xiàng)以及常見報(bào)錯(cuò)原因

    在c語言當(dāng)中我們要計(jì)算一個(gè)數(shù)的n次方時(shí)候,可以使用多種方法,但是也有一種比較簡單的方法,便是調(diào)用一個(gè)函數(shù)pow函數(shù),下面這篇文章主要給大家介紹了關(guān)于C語言中pow函數(shù)使用方法、注意事項(xiàng)以及常見報(bào)錯(cuò)原因的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • C語言實(shí)現(xiàn)簡單的貪吃蛇小游戲

    C語言實(shí)現(xiàn)簡單的貪吃蛇小游戲

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)簡單的貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • C++ 讀寫文件安全又簡潔的簡單實(shí)例

    C++ 讀寫文件安全又簡潔的簡單實(shí)例

    這篇文章主要介紹了C++ 讀寫文件安全又簡潔的簡單實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • C語言動(dòng)態(tài)內(nèi)存規(guī)劃詳解

    C語言動(dòng)態(tài)內(nèi)存規(guī)劃詳解

    這篇文章主要介紹了C語言動(dòng)態(tài)內(nèi)存的規(guī)劃,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-10-10
  • C語言入門篇--理解地址及內(nèi)存

    C語言入門篇--理解地址及內(nèi)存

    本篇文章是基礎(chǔ)篇,適合c語言剛?cè)腴T的朋友,本文主要介紹了c語言的內(nèi)存及地址,幫助大家快速入門c語言的世界,更好的理解c語言
    2021-08-08
  • C語言實(shí)現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用集合(HashSet)

    C語言實(shí)現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用集合(HashSet)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用集合,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C語言實(shí)現(xiàn)手寫Map(數(shù)組+鏈表+紅黑樹)的示例代碼

    C語言實(shí)現(xiàn)手寫Map(數(shù)組+鏈表+紅黑樹)的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用C語言實(shí)現(xiàn)手寫Map(數(shù)組+鏈表+紅黑樹),文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)有一定借鑒價(jià)值,需要的可以參考一下
    2022-09-09

最新評論