如何在两个 C++11 线程中实现线程同步?
How to achieve thread synchronization in two C++11 Threads?
情况:
A Factory
class 成员函数 manager
生成两个 worker
线程。每个 worker
线程 运行 一年中的每一天都有一个循环,并递增它们自己的变量 workHours
和一个共享变量 work
。在每天结束时,每个 worker
线程都会发出信号 manager
以获取其 work
和 workHours
的报告
当 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;
}
情况:
A Factory
class 成员函数 manager
生成两个 worker
线程。每个 worker
线程 运行 一年中的每一天都有一个循环,并递增它们自己的变量 workHours
和一个共享变量 work
。在每天结束时,每个 worker
线程都会发出信号 manager
以获取其 work
和 workHours
的报告
当 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;
}