Home > OS >  How to make destructor wait until other thread's job complete?
How to make destructor wait until other thread's job complete?

Time:08-15

I have one main thread that will send an async job to the task queue on the other thread. And this main thread can trigger a destroy action at any time, which could cause the program to crash in the async task, a piece of very much simplified code like this:

class Bomb {
public:
    int trigger;
    mutex my_mutex;
};

void f1(Bomb *b) {
    lock_guard<std::mutex> lock(b->my_mutex); //won't work! Maybe b have been destructed!
    sleep(1);
    cout<<"wake up.."<<b->trigger<<"..."<<endl;
}

int main()
{
    Bomb *b = new Bomb();
    b->trigger = 1;
    thread t1(f1, b);
    sleep(1);
    //lock here won't work
    delete b;//in actual case it is triggered by outside users
    
    t1.join();

    return 0;
}

The lock in f1 won't work since the destructor can be called first and trying to read mutex will crash. Put lock in destructor or before the delete also won't work for the same reason.

So is there any better way in this situation? Do I have to put mutex in the global scope and inside destructor to solve the issue?

CodePudding user response:

In code, my comment looks like this :

#include <future>
#include <mutex>
#include <iostream>
#include <chrono>
#include <thread>

// do not use : using namespace std;

class Bomb 
{
public:
    void f1() 
    {
        m_future = std::async(std::launch::async,[this]
        {
            async_f1();
        });
    }
private:

    void async_f1()
    {
        using namespace std::chrono_literals;

        std::lock_guard<std::mutex> lock{ m_mtx };
        std::cout << "wake up..\n";
        std::this_thread::sleep_for(1s);
        std::cout << "thread done.\n";
    }

    std::future<void> m_future;
    std::mutex m_mtx;
};


int main()
{
    {
        std::cout << "Creating bomb\n";
        Bomb b; // no need to use unecessary new
        b.f1();
    }
    std::cout << "Bomb destructed\n";

    return 0;
}
  • Related