The timer hangs in the main topic

I am trying to implement a timer with a standard environment. Here is the code that 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 a result, I see the output after 5 seconds:

 // 5 seconds left On Timer main function 

Bit I'd like:

 main function // 5 seconds left On Timer 

It seems that my implementation also hangs in the main thread. How to avoid this?

+5
source share
2 answers

Your std :: async command returns std :: future, which is immediately destroyed. The problem is that destroying the future means β€œmerging” the thread you created, which means that the destructor will wait until the thread ends and the code in your main thread continues to progress until this process completes.

The simple answer is to assign the result of your call to std :: async to a variable and possibly call its get () function in your loop that checks for completion.

 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(); 
+3
source
 std::async(std::launch::async, [&] () { std::this_thread::sleep_for( std::chrono::milliseconds{5000}); std::cout << "On TIMER!" << std::endl; } ); 

It does not work unless you assign the variable std::future returned by std::async variable and save it. I did not know why this was so, because I could not understand how it looked. Vincent Savard did and linked us to the destructor documentation for std::future , which states:

it can be blocked if all of them are true: the general state was created by calling std :: async, the general state is not ready yet, and this was the last link to the general state.

Since the returned std::future not attached to anything, it is instantly destroyed, and the destructor is blocked until completion.

I am going to leave the signal handler since it is not related 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; } 
+3
source

Source: https://habr.com/ru/post/1260305/


All Articles