Sleep an Async Task
Asked Answered
C

2

9

In my project I need to poll some devices every n seconds and sleep and continue forever. I have created an async task with launch as async instead of std::thread. But if I use std::this_thread::sleep_for() inside an async task with launch as async, it looks like its actually blocking my main thread? The following program outputs "Inside Async.." forever, it never prints "Main function".

Instead of async, if I use a std::thread(), it would work fine. But I wanted to use an async task as I don't have to join it and manage its lifetime unlike a thread.

How do I make an async task sleep?

#include <iostream>
#include <future>
#include <thread>

int main() 
{
    std::async(std::launch::async,
    []()
    {
        while(true)
        {
            std::cout <<"Inside async.."<< std::endl;   
            std::this_thread::sleep_for(std::chrono::seconds(2));
        }
    });

    std::cout <<"Main function"<< std::endl;
    return 0;
}
Chenab answered 22/8, 2017 at 12:27 Comment(3)
If you simply detach a thread, you "don't have to join it and manage its lifetime" any more.Samsara
There was a time when we had documentation for this.Thynne
@samvar Detaching isn't simple if you want your program to ever terminate cleanly.Austine
T
10

std::async returns a std::future which waits for the task to finish in its destructor. Save the std::future somewhere to delay the destructor:

auto future = std::async(...).

Thynne answered 22/8, 2017 at 12:31 Comment(1)
This, and be aware that std:.async isn't strictly required to run asynchronously at all (the standard says "as if in a new thread of execution"... as if, whatever that is), so sleeping within it may be not the best idea anyway.Interatomic
C
4

std::async returns a std::future which is immediately destroyed (it is a temporary which is not prolonged by const reference or moved into some object).

the destructor of std::future blocks until the asynchronous result that std::future presents is finished. since your asynchronous task is not finished, the call for std::async blocks forever.

prolonging the lifetime of the future will not help, because its destructor will block at some point, your asynchronous task never ends. using std::thread seems appropriate here.

In fact, I will advise you to use some third-pary timer implementation, as what you want is an asynchronous task that executes periodically. this is perfect for timers.

Christopher answered 22/8, 2017 at 12:31 Comment(4)
You want the destructor to block at some point, usually before main exits.Thynne
@Thynne If I don't care about the asynchronous task result, then you won't want to block.Christopher
I'm not sure what the standard says about threads that outlive the main thread. I think that is not ok.Thynne
The standard is clear in that havng threads outlive main is undefined behaviour. You can be slack and pray, you can have a non-clean shutdown, you can exit before main ends (I believe also undefined what it does to running threads). Or you can keep track of your threads. Keeping track of threads is not hard.Austine

© 2022 - 2024 — McMap. All rights reserved.