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

How to achieve thread synchronization in two C++11 Threads?

情况:

A Factory class 成员函数 manager 生成两个 worker 线程。每个 worker 线程 运行 一年中的每一天都有一个循环,并递增它们自己的变量 workHours 和一个共享变量 work。在每天结束时,每个 worker 线程都会发出信号 manager 以获取其 workworkHours 的报告 当 manager 从两个 worker 线程获得 workHours 时,它将 totalWorkHours 报告为 (workHours[0] + workHours[1]) 到 boss

问题:

线程未按预期工作。在向经理报告之前,线程处于多个循环中 运行ning。它们不会针对每天的报告进行同步。 如何实现线程同步,每天之后,两个线程都向管理器报告它们的统计信息。

代码:

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

#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;
}

我自己解决了。发在这里供参考。

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;
}