如何在两个C ++ 11线程中实现线程同步?

时间:2018-04-20 02:42:43

标签: multithreading c++11 thread-synchronization

情况:

Factory类成员函数manager产生两个worker个线程。每个worker线程为一年中的每一天运行一个循环,并递增它们自己的变量workHours和共享变量work。在每天结束时,每个worker主题信号manager都会发出workworkHours的报告 当managerworkHours个帖子获得worker时,它会totalWorkHoursworkHours[0] + workHours[1]报告boss

问题:

线程未按预期工作。在向管理器报告之前,线程在多个循环中运行。它们不会在每天报告时同步。 如何实现这个线程同步,在每天之后,两个线程都将其统计信息报告给经理。

代码:

[以下代码没有编译错误,如果你想测试运行,编辑]

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

using namespace std;

class Factory{

public:
    Factory() {
        work = 0; 
        workHours[0] = 0; 
        workHours[1] = 0;
    };
    void manager();

private:
    std::thread threads[2];
    std::mutex m_lock;
    std::condition_variable cond[2];

    int work;               // Shared across threads
    int workHours[2];       // One var for each thread
    int totalWorkHours;

    void worker(int id);
    void boss(int work, int workHours);
};

void Factory::worker(int id)
{
    cout<< id <<" Started Working "<<endl;
    for (int day = 0; day<365; day++)
    {
        std::unique_lock<std::mutex> lck{ m_lock };
        work++;
        workHours[id]++;
        cout << id << " working " << endl;
        cond[id].notify_one();
        lck.unlock();
        std::this_thread::sleep_for(1s);
    }
}


void Factory::manager()
{
    int wHrs0, wHrs1;

    threads[0] = std::thread([&](Factory *fac) { fac->worker(0); }, this);
    threads[1] = std::thread([&](Factory *fac) { fac->worker(1); }, this);

    //for (int day=0; day<365; day++)
    for (;;)
    {
        std::unique_lock<mutex> lck0{ m_lock };
        cond[0].wait(lck0);
        cout << "Worker0 workHours : " << workHours[0] << "  Total Work : " << work << endl;
        wHrs0 = workHours[0];
        lck0.unlock();

        std::unique_lock<mutex> lck1{ m_lock };
        cond[1].wait(lck1);
        cout << "Worker1 workHours : " << workHours[1] << "  Total Work : " << work << endl;
        wHrs1 = workHours[1];
        lck1.unlock();

        totalWorkHours = wHrs0 + wHrs1;

        cout << "Both Workers Worked one day" << endl;
        boss(work, totalWorkHours);
    }
}

void Factory::boss(int work, int workHours)
{
    cout << "I am not Happy with just " << work << " amount of work in damn " << workHours << " Hrs " << endl;
}

int main()
{
    Factory nike;
    nike.manager();

    //wait for keypress
    cin.get();

    return 0;
}

1 个答案:

答案 0 :(得分:0)

我自己解决了。在此发布以供参考。

worker等待manager使用工作结果。并且manager等待worker两个人完成一天的工作。

// Example program
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>

using namespace std;

class Factory{

public:
    Factory() {
        work = 0; 
        workHours[0] = 0; 
        workHours[1] = 0;
    };
    void manager();

private:
    std::thread threads[2];
    std::mutex m_lock;
    std::condition_variable cond[2];
    std::condition_variable condMan;
    bool resFetch[2];
    bool resAvailable[2];

    int work;               // Shared across threads
    int workHours[2];       // One var for each thread

    int totalWorkHours;

    void worker(int id);
    void boss(int work, int workHours);
};

void Factory::worker(int id)
{
    cout<< id <<" Started Working "<<endl;
    for (int day = 0; day<365; day++)
    {
        std::unique_lock<std::mutex> lck{ m_lock };
        while(!resFetch[id])
            condMan.wait(lck);

        resFetch[id] = false;

        work++;
        workHours[id]++;
        cout << id << " working " << endl;
        resAvailable[id] = true;
        cond[id].notify_one();
        lck.unlock();

        std::this_thread::sleep_for(1s);
    }
}

void Factory::manager()
{
    int wHrs0, wHrs1;

    threads[0] = std::thread([&](Factory *fac) { fac->worker(0); }, this);
    threads[1] = std::thread([&](Factory *fac) { fac->worker(1); }, this);

    for (;;)
    {
        std::unique_lock<std::mutex> lck{ m_lock };

        resFetch[0] = true;
        resFetch[1] = true;

        condMan.notify_all();

        while(!resAvailable[0])
            cond[0].wait(lck);
        cout << "Worker0 workHours : " << workHours[0] << "  Total Work : " << work << endl;
        wHrs0 = workHours[0];
        resAvailable[0] = false;

        while (!resAvailable[1])
            cond[1].wait(lck);
        cout << "Worker1 workHours : " << workHours[1] << "  Total Work : " << work << endl;
        wHrs1 = workHours[1];
        resAvailable[1] = false;

        lck.unlock();

        totalWorkHours = wHrs0 + wHrs1;

        cout << "Both Workers Worked one day" << endl;
        boss(work, totalWorkHours);
    }
}

void Factory::boss(int work, int workHours)
{
    cout << "I am not Happy with just " << work << " amount of work in damn " << workHours << " Hrs " << endl;
}

int main()
{
    Factory nike;
    nike.manager();

    //wait for keypress
    cin.get();

    return 0;
}