Consider the next C++ code fragment which represnets (pseudo) multi thread application which has two threads, the main thread responsible for getting new data (e.g., new frame from video stream) and the secondary thread which needs to process the data (e.g., filter the frame), this should happen in parallel so, for example, when the main thread acquires the first frame the second thread does not do anything, when the main thread acquires the second frame the second thread process the first frame and so on.
#include <iostream>
#include <mutex>
#include <condition_variable>
using namespace std;
bool StartProcessFromMain = false;
bool FinishedProcess = false;
mutex Main2Process;
mutex Process2Main;
condition_variable CVMain2Process;
condition_variable CVProcess2Main;
void Process();
int main()
{
long long int Iter = 0;
// start data process thread
thread ProcessThread(Process);
StartProcessFromMain = true;
CVMain2Process.notify_one();
// this is the main data acquiring thread
unique_lock<mutex> lk2(Process2Main);
lk2.unlock();
while (true)
{
cout << "Iteration: " << ++Iter << endl;
cout << "Waiting for data processing to finish" << endl;
lk2.lock();
CVProcess2Main.wait(lk2, [&] {return FinishedProcess; });
FinishedProcess = false;
lk2.unlock();
cout << "Data processing ended..... getting new data" << endl;
// getting new data
cout << "Got new data, calling process thread" << endl;
StartProcessFromMain = true;
CVMain2Process.notify_one();
}
return 0;
}
void Process()
{
//data processing thread
unique_lock<mutex> lk(Main2Process);
lk.unlock();
while (true)
{
cout << "waiting for new data" << endl;
lk.lock();
CVMain2Process.wait(lk, [&] {return StartProcessFromMain; });
StartProcessFromMain = false;
lk.unlock();
// Processing new data here
// Finished processing new data - notify data acquiring thread
cout << "Finished processing new data" << endl;
FinishedProcess = true;
CVProcess2Main.notify_one();
}
}
In practice, compiled both with MSVC 2015 (x64) on Windows 10 and with gcc on Ubuntu 16.04, this code always hangs forever (usually after thousands or tens of thousands iterations) when both threads wait one for the other :-(
What am I doing wrong here?
Aucun commentaire:
Enregistrer un commentaire