简体   繁体   中英

C++ What possible ways can a detached thread signal it is terminating?

I had three initial ideas about this

  • Firstly some kind of counter? (Maybe using mutex?)
  • Some kind of semophore? (I don't know much about these) OR perhaps a promise / future combination
  • Some other kind of signal/slot mechanism, similar to that of the signal created by CTRL-C (SIGINT etc)

I'm working on some software which makes use of detached threads to do some work. Unfortunatly the threads don't clean up nicely, they just quit at the end of execution. This is fine for communication in one direction (ie; main() can quit first), but won't work the other way around - at the moment there is no way for main() to know when the threads have finished working and to exit gracefully.

To expand on those bullet points...

My initial idea was to have a protected region of variables - could be a counter or an array of flags, one for each thread, and to access these using a mutex. The mutex might not even be necessary if using one variable per detached thread to signal the end of the thread working, because main() will "poll" these variables, which is a read-only operation. Only the detached threads themselves need write access. If more than one detached thread uses the same counter/variable then a mutex would be required.

The next idea I had was to use a semophore (which is something I really know nothing about) or promise / future combinations, which I think would work as a possible option.

The final thought was some kind of signals mechanism, like possibly "stealing" a SIGxyz signal (like SIGINT) and using that to some how communicate the end of a thread execution. I'm not confident about this one however.

My question is really - how is this supposed to be done? What would the typical engineering solution to this problem be?

(Final thought: Using a file, or a pipe? Seems a bit complicated though?)

Perhaps I overlooked the question but I think you could use an atomic variable as a flag in order to notify the detached thread's termination.

Something like the following example:

#include <thread>
#include <iostream>
#include <atomic>

int main()
{
    // Define a flag to notify detached thread's termination
    std::atomic_bool term_flag;

    // Define some function to run concurrently
    auto func = [&term_flag](){
        std::this_thread::sleep_for(std::chrono::seconds(2));
        term_flag = true;
    };

    // Run and detach the thread
    term_flag = false;
    std::thread t(func);
    t.detach();

    // Wait until detached thread termination
    while(!term_flag)
        std::this_thread::yield();

    std::cout << "Detached Thread has terminated properly" << std::endl;

    return 0;
}

Output:

Detached Thread has terminated properly


EDIT:

As Hans Passant mentioned, you could also use a condition variable associated with a mutex to do it.
This would be a better solution (but a bit less readable in my humble opinion) since we have more control over how much to wait.

The basic example above could then be rewritten as:

#include <thread>
#include <iostream>
#include <mutex>
#include <condition_variable>

int main()
{
    // Define the mutex and the condition variable to notify the detached thread's termination
    std::mutex m;
    std::condition_variable cv;

    // Define some function to run concurrently
    auto func = [&cv](){
        std::this_thread::sleep_for(std::chrono::seconds(2));
        cv.notify_one();
    };

    // Run and detach the thread
    std::thread t(func);
    t.detach();

    // Wait until detached thread termination
    {
        std::unique_lock<std::mutex> lk(m);
        cv.wait(lk);
    }

    std::cout << "Detached Thread has terminated properly" << std::endl;

    return 0;
}

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