简体   繁体   中英

Timer hangs main thread

I'm trying to implement timer with standard environment Here is a code I have:

bool shutdownDetected = false;

void signal_handler(const int sigid)
{
    shutdownDetected = true;
}

int main(int argc, const char * argv[])
{
    signal(SIGTERM, (sig_t)signal_handler);

    std::async(std::launch::async, [&] () {
        std::this_thread::sleep_for( std::chrono::milliseconds{5000});
        std::cout << "On TIMER!" << std::endl;
    } );

    std::cout << "main function" << std::endl;

    while (!shutdownDetected) {
    }

    return EXIT_SUCCESS;
}

As result I see in output after 5 seconds:

// 5 seconds left
On Timer
main function

but would like to see:

main function
// 5 seconds left
On Timer

Seems that my implementation hangs main thread as well. How to avoid this?

Your std::async command returns an std::future, which is then immediately destroyed. The problem is that destruction of a future involves 'joining' the thread you created, which means that the destructor is going to wait until the thread has ended itself and code execution in your main thread doesn't advance until that process has completed.

Simple answer is to assign the result of your std::async call to a variable, and possibly call its get() member function in your loop that tests for termination.

auto t = std::async(std::launch::async, [&] () {
    std::this_thread::sleep_for( std::chrono::milliseconds{5000});
    std::cout << "On TIMER!" << std::endl;
} );

std::cout << "main function" << std::endl;

t.get();
std::async(std::launch::async, [&] () {
        std::this_thread::sleep_for( std::chrono::milliseconds{5000});
        std::cout << "On TIMER!" << std::endl;
    } );

Does not work unless you assign the std::future returned by std::async to a variable and keep it around. I did not know why this is, clearly because I couldn't be bothered to look it up. Vincent Savard did, and linked us to documentation on the destructor for std::future which says:

it may block if all of the following are true: the shared state was created by a call to std::async, the shared state is not yet ready, and this was the last reference to the shared state.

Since the returnded std::future is not assigned to anything, it is instantly destroyed and the destructor blocks until completion.

I'm going to leave out the signal handler as it's not relevant to the problem.

#include <iostream>
#include <future>

int main()
{
    auto letMeLive = std::async(std::launch::async, [] () {
        std::this_thread::sleep_for( std::chrono::milliseconds{5000});
        std::cout << "On TIMER!" << std::endl;
    } );

    std::cout << "main function" << std::endl;

    letMeLive.wait(); // instead of the signal handler
    return EXIT_SUCCESS;
}

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