交替运行线程+等待多个线程

时间:2019-03-17 17:43:27

标签: c++ multithreading c++11 concurrency condition-variable

这是我的第一个问题,因此,如果我不够精确,请告诉我,我会尽力阐述。

考虑以下程序:

我同时拥有两个函数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

我该如何实施/我的错误在哪里?

谢谢您的时间!

0 个答案:

没有答案