I am completely begginner in C++ and threads as well. I have made a very simple example of my problem. In the code I provide, I create threads and detach them. Each thread executes a different function: one which consists in pushing an int into a queue, and the other one reads that value and simulate a long processing with the read value and the function's argument. The queue object is protected by a mutex as it is shared between the two threads. I know that my code is a bit stupid but I have made it to represent my real problem, which uses detached threads and a shared queue protected by mutex.
Here's the code:
#include <mutex>
#include <iostream>
#include <thread>
#include <queue>
using namespace std;
std::queue<int> tasks;
std::mutex m;
void push_task(int arg) {
printf("[Pushing task into the queue]");
m.lock();
tasks.push(arg);
m.unlock();
}
void process_task(int number) {
printf("[Processing task from the queue]");
m.lock();
while (tasks.empty() == false){
int task = tasks.front();
tasks.pop();
printf("[Processing...]");
std::this_thread::sleep_for(std::chrono::milliseconds((task+number)*1000)); //simulate some execution
printf("[Task has been successfully processed]");
}
m.unlock();
}
int launch_threads(int nTask, int n){
int counter = 0;
while(counter < 8){
std::thread(push_task, nTask).detach();
std::thread(process_task, n).detach();
counter++;
}
printf("[Launch Threads Ends]");
return 0;
}
int main(){
launch_threads(0, 10000);
printf("[Main Ends]");
return 0;
}
Well, the problem I am facing is that I got the following error:
mutex destroyed while busy
I have investigate and I have read (correct me if I am wrong) that this happens because the calling function, in my case launch_threads(), ends while the local threads created inside it are still running and therefore the mutex can still be owned by some thread (is busy), giving that error. In fact, no processing inside the threads really ends.
My question is: How can I avoid that error?
I have also read that not making the threads as local variables may solve the problem. In that case, how can I declare the threads as global, if I am passing a function with an argument to them?
Extra question related to the topic: May using std::lock_guard lock(m) help to avoid the problem?
Thank you in advance!