簡體   English   中英

同步C ++中的三個線程

[英]Synchronize three Threads in C++

我有以下程序(組成示例!):

#include<thread>
#include<mutex>
#include<iostream>

class MultiClass {
    public:
        void Run() {
            std::thread t1(&MultiClass::Calc, this);
            std::thread t2(&MultiClass::Calc, this);
            std::thread t3(&MultiClass::Calc, this);
            t1.join();
            t2.join();
            t3.join();
        }
    private:
        void Calc() {
            for (int i = 0; i < 10; ++i) {
                std::cout << i << std::endl;
            }
        }
};

int main() {
    MultiClass m;
    m.Run();
    return 0;
}

我需要按以下方式同步循環迭代,但我無法提出解決方案(我已經使用互斥體擺弄了大約一個小時,但找不到該組合): t1t2應該進行一次循環迭代,然后t3將執行一次迭代,然后再次t1t2將執行一次,然后t3將執行一次。

因此,您看到,我需要t1t2同時執行操作,並且在進行一次迭代之后, t3應該自己進行一次迭代。

您能否指出我將如何實現這一目標? 就像我說的,我一直在嘗試使用互斥鎖,但無法提出解決方案。

使用兩個條件變量,這是一個草圖。

線程1和2等待條件變量segment_1

std::condition_variable segment_1;

線程3等待條件變量segment_2

std::condition_variable segment_2;

線程1和2應該在segment_1上使用wait() ,線程3應該在segment_2上使用wait() 要啟動線程1和2,請在segment_1上調用notify_all() ,一旦完成,請在segment_2上調用notify_one()來啟動線程3。您可能希望使用某些控制線程來控制序列,除非可以進行鏈接(即1和2完成后,最后一個要完成的調用將通知線程3,依此類推。)

這並不完美(請參閱丟失的喚醒)

如果您真的想使用給定的線程結構手動執行此操作,則可以使用以下方法*:

class SyncObj {
    mutex mux;
    condition_variable cv;  
    bool completed[2]{ false,false };

public:
    void signalCompetionT1T2(int id) {
        lock_guard<mutex> ul(mux);
        completed[id] = true;
        cv.notify_all();
    }
    void signalCompetionT3() {
        lock_guard<mutex> ul(mux);
        completed[0] = false;
        completed[1] = false;
        cv.notify_all();
    }
    void waitForCompetionT1T2() {
        unique_lock<mutex> ul(mux);             
        cv.wait(ul, [&]() {return completed[0] && completed[1]; });         
    }
    void waitForCompetionT3(int id) {
        unique_lock<mutex> ul(mux);         
        cv.wait(ul, [&]() {return !completed[id]; });           
    }       
};

class MultiClass {
public:
    void Run() {
        std::thread t1(&MultiClass::Calc1, this);
        std::thread t2(&MultiClass::Calc2, this);
        std::thread t3(&MultiClass::Calc3, this);
        t1.join();
        t2.join();
        t3.join();
    }
private:
    SyncObj obj;
    void Calc1() {
        for (int i = 0; i < 10; ++i) {
            obj.waitForCompetionT3(0);
            std::cout << "T1:" << i << std::endl;
            obj.signalCompetionT1T2(0);
        }           
    }
    void Calc2() {
        for (int i = 0; i < 10; ++i) {
            obj.waitForCompetionT3(1);
            std::cout << "T2:" << i << std::endl;
            obj.signalCompetionT1T2(1);
        }
    }
    void Calc3() {      
        for (int i = 0; i < 10; ++i) {
            obj.waitForCompetionT1T2();
            std::cout << "T3:" << i << std::endl;
            obj.signalCompetionT3();
        }       
    }
};

但是,如果每次迭代的計算量都很大,則這只是一種合理的方法,因此您可以忽略同步開銷。 如果不是這種情況,您可能最好看看適當的並行編程庫,例如intel的tbb或microsofts ppl。

*)注意:此代碼未經測試且未經優化。 我只是寫了它,以表明總體結構是什么樣子

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM