C++11 並發之std::thread std::mutex


https://www.cnblogs.com/whlook/p/6573659.html

(https://www.cnblogs.com/lidabo/p/7852033.html)

C++:線程(std::thread)

 

1.創建一個線程

  創建線程比較簡單,使用std的thread實例化一個線程對象就創建完成了,示例:

#include <iostream>
#include <thread>
using namespace std;

void t1()  //普通的函數,用來執行線程
{
    for (int i = 0; i < 20; ++i)
    {
        cout << "t1111\n";
    }
}
void t2()
{
    for (int i = 0; i < 20; ++i)
    {
        cout << "t22222\n";
    }
}
int main()
{
    thread th1(t1);  //實例化一個線程對象th1,使用函數t1構造,然后該線程就開始執行了(t1())
    thread th2(t2);

    cout << "here is main\n\n";

    return 0;
}

 

不過這個示例是有問題的,因為在創建了線程后線程開始執行,但是主線程main()並沒有停止腳步,仍然繼續執行然后退出,此時線程對象還是joinable的,線程仍然存在但指向它的線程對象已經銷毀,所以會拋出異常。

 

那么該如何保證子線程執行完了退出后再退出主線程呢?

2.thread::join()

  使用join接口可以解決上述問題,join的作用是讓主線程等待直到該子線程執行結束,示例:

#include <iostream>
#include <thread>
using namespace std;

void t1()
{
    for (int i = 0; i < 20; ++i)
    {
        cout << "t1111\n";
    }
}
void t2()
{
    for (int i = 0; i < 20; ++i)
    {
        cout << "t22222\n";
    }
}
int main()
{
    thread th1(t1);
    thread th2(t2);
    
    th1.join(); //等待th1執行完
    th2.join(); //等待th2執行完

    cout << "here is main\n\n";

    return 0;
}

此時就可以正常地執行子線程了,同時注意最后一個輸出,說明了main是等待子線程結束才繼續執行的

需要注意的是線程對象執行了join后就不再joinable了,所以只能調用join一次。

3.thread::detach()

  (1.)中提到的問題,還可以使用detach來解決,detach是用來和線程對象分離的,這樣線程可以獨立地執行,不過這樣由於沒有thread對象指向該線程而失去了對它的控制,當對象析構時線程會繼續在后台執行,但是當主程序退出時並不能保證線程能執行完。如果沒有良好的控制機制或者這種后台線程比較重要,最好不用detach而應該使用join。

int main()
{
    thread th1(t1);
    thread th2(t2);
    
    th1.detach();
    th2.detach();

    cout << "here is main\n\n";

    return 0;
}

由結果可見線程並沒有執行完而退出:

 

4.mutex

  頭文件是<mutex>,mutex是用來保證線程同步的,防止不同的線程同時操作同一個共享數據。

但是使用mutex是不安全的,當一個線程在解鎖之前異常退出了,那么其它被阻塞的線程就無法繼續下去。

5.std::lock_guard

  使用lock_guard則相對安全,它是基於作用域的,能夠自解鎖,當該對象創建時,它會像m.lock()一樣獲得互斥鎖,當生命周期結束時,它會自動析構(unlock),不會因為某個線程異常退出而影響其他線程。示例:

int cnt = 20;
mutex m;
void t1()
{
    while (cnt > 0)
    {    
        lock_guard<mutex> lockGuard(m); if (cnt > 0)
        {
            --cnt;
            cout << cnt << endl;
        }
        
    }
}
void t2()
{
    while (cnt > 0)
    {
        lock_guard<mutex> lockGuard(m);
        if (cnt > 0)
        {
            --cnt;
            cout << cnt << endl;
        }
    
    }
}

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM