简体   繁体   中英

Detached Threads: mutex destroyed while busy Error C++

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!

You launch some threads and detach them. Then you let the main function return which terminates the process . That process termination kills all threads and also causes all global objects to be destructed.

You should only exit the thread that the main function is running in, which lets the detached threads continue running in the process (which then exits when the last thread have exited).

There's currently no way to exit a thread in the C++ standard library, so you have to use system-dependent functions. For example in POSIX systems (like Linux or macOS) you use the pthread_exit function.


There are of course two other possible solutions:

  1. Don't detach the threads, and join them before exiting from main . This might not always be possible or desired though.

  2. Wait inside the main function for the detached threads to exit, using some other kind of waiting or polling mechanism that the threads have exited. This might also not be desired. And could be problematic if the threads set a flag inside the threads themselves that the main function checks, which might lead to a race condition where the thread haven't actually exited before the main function returns.

Your main function ends - and so does your whole program. Any other threads can't stop this - so you have to wait for them to finish (see std::thread::join). That is probably all you need. But whats with mutex? All program resources are destroyed at the end of a program - and you can't destroy busy mutex (see std::lock_guard)

Update: noticed another bad thing - you didn't synchronize threads - so producing/consuming threads will have data race and it is not guaranteed that all your data is processed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM