这是我的第一个问题,因此,如果我不够精确,请告诉我,我会尽力阐述。
考虑以下程序:
我同时拥有两个函数void a()
和void i()
的线程。
a()
的每个线程在循环中对一组不同的数据执行某种计算,而i()
的相应线程(再次在循环中)对同一数据执行另一种计算。
函数a()
和i()
必须交替运行,但是a()
必须等待i()
的所有线程完成(循环一个周期),然后才能运行它应该恢复。 i()
的每个线程仅需等待,直到a()
的相应线程完成计算。
void a(int N, datatype data){
for (int j = 0; j != N; j++){
//wait until all threads of i() are finished
//calculate something with data
//notify i()
}
}
void i(int N, datatype data){
for (int j = 0; j != N; j++){
//wait until corresponding thread of a() is finished
//calculate something with data
//notify a()
}
}
我熟悉标准库的条件变量和锁。 我仍然不知道如何实现上述行为。
我用一个小的测试程序尝试了一下,该程序只打印出数据,但输出结果却不是预期的。
测试程序:
#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>
using namespace std;
const int O = 2;
const int N = 2;
mutex m, n;
condition_variable a_finished[O];
condition_variable i_finished;
bool i_done[O];
bool check(bool* b){
bool tmp = true;
for (int j = 0; j != O; j++){
if (b[j] == false){
return false;
}
}
return true;
}
void printR(const char* c, int p){
lock_guard<mutex> lockg(n);
cout << c << p << " running!\n";
}
void print(int j, const char* c, int p){
lock_guard<mutex> lockg(n);
cout << c << p << ": " << j << "\n";
}
void a(int N, int p){
printR("a", p);
for (int j = 0; j != N; j++){
unique_lock<mutex> lock(m);
i_finished.wait(lock, [&](){return check(i_done); });
//cout << check(i_done) << "\n";
print(j, "a", p);
lock.unlock();
a_finished[p].notify_all();
}
}
void i(int N, int p){
printR("i", p);
i_done[p] = true;
for (int j = 0; j != N; j++){
unique_lock<mutex> lock(m);
a_finished[p].wait(lock);
i_done[p] = false;
print(j, "i", p);
i_done[p] = true;
lock.unlock();
i_finished.notify_all();
}
}
int main() {
for (int c = 0; c != O; c++){
i_done[c] = false;
}
thread a_threads[O];
thread i_threads[O];
for (int c = 0; c != O; c++){
a_threads[c] = thread(a, N, c);
i_threads[c] = thread(i, N, c);
}
this_thread::sleep_for(chrono::seconds(2));
i_finished.notify_all();
for (int c = 0; c != O; c++){
a_threads[c].join();
i_threads[c].join();
}
}
输出应类似于:
i0 running!
a0 running!
i1 running!
a1 running!
a0: 0
a1: 0
i0: 0
i1: 0
a1: 1
i1: 1
a0: 1
i0: 1
a1: 2
a0: 2
i0: 2
i1: 2
...
即确认所有线程都在运行,
然后是a()
的每个线程在i()
的相应线程之前(对于每个步骤;直到达到N)。
相反,我得到了:
a0 running!
i0 running!
a1 running!
i1 running!
a1: 0
a1: 1
i1: 0
a0: 0
a0: 1
i0: 0
我该如何实施/我的错误在哪里?
谢谢您的时间!