I write a multi-threaded C++ program using std::thread that looks like the following:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
const int threadNum = 4;
mutex mt[threadNum];
condition_variable cv[threadNum];
thread threadList[threadNum];
bool threadWork[threadNum];
void work(int id) {
while (true) {
unique_lock<mutex> lck(mt[id]);
cv[id].wait(lck, [&]() { return threadWork[id]; }); // wait for incoming tasks
// do something
threadWork[id] = false;
cv[id].notify_all();
}
}
int main() {
for (int i = 0; i < threadNum; i ++) {
threadWork[i] = false;
threadList[i] = thread(work, i);
}
while (true) {
for (int i = 0; i < threadNum; i ++) {
// allocate tasks for each threads
threadWork[i] = true;
cv[i].notify_all();
}
for (int i = 0; i < threadNum; i ++) {
// wait until all tasks finish
unique_lock<mutex> lck(mt[i]);
cv[i].wait(lck, [&]() { return !threadWork[i]; });
cout << "Finish thread " << i << endl;
}
// do something
}
for (int i = 0; i < threadNum; i ++)
threadList[i].join();
return 0;
}
In iterations of the program, the main thread and sub threads will execute alternatively. The main thread will first allocate tasks for multiple sub threads. After all threads finish their tasks, the main thread will aggregate the information and do some other computation.
However, during execution, the program will crash or get stuck in dead locks after a few iterations randomly. I have no idea why this happens. What the problem with it?
My environment: ubuntu 22.04, g++ 11.4
Coments in code below:
You should try, for your experiment something a bit easier, let's say, with only one block of guarded data, to start with. Here's an example below.
Note in the code below that the worker threads wait for the one unique condition variable telling them that something needs done.
I've also added a simple mechanism to exit gracefully from the program once the work is done. That's as important as the rest, note the use of atomic<>, which guarantees that all cores will see the change in value as soon as it's made.