2

I'm writing in pure c++11 and want to do a simple 'wait x seconds and turn on a member variable' after turning it off. The member variable of the class in this example is a flag for 'animating'.

        cout << "stop animating!" << endl;
        this->animating = false;

        async(launch::async, [this] ()
        {
            this_thread::sleep_for(chrono::seconds{8});
            this->animating = true;
            std::cout << "start animating!" << std::endl;               
        });
        cout << "i'm here" << endl;

the this_thread::sleep_for blocks the entire program from continuing on (even though it is inside an async thread). because i dont see "I'm here" 8 seconds later. If the above code worked as intended, i would see "I'm here" immediately after "stop animating". This blocking is a problem for me because it locks up everything I care about like continuing to process 'input' like keyboard events, and the program also stops 'drawing' other objects on the screen.

Does anyone know how to achieve a simple delayed and async change of a member variable using standard c++11 (no frameworks like boost please)

in iOS it is very simple:

// Delay execution of my block for 10 seconds.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC), 
dispatch_get_main_queue(), ^
{
    //do whatever, 10 seconds later
});
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
user1709076
  • 2,538
  • 9
  • 38
  • 59
  • 2
    Either use `std::thread([this](){...}).detach();` instead or try saving the result std::future and make sure it doesn't go out of scope. –  Mar 17 '18 at 18:32
  • yes. this appears to work, even better than keeping track of the auto future returned from async. i think this is the answer – user1709076 Mar 17 '18 at 18:56
  • 1
    Maybe have a look at this [answer](https://stackoverflow.com/a/32517201/3972710). As user2176127 mentioned it you may save the std::future otherwise its destructor waits for its result – NGI Mar 17 '18 at 19:39

1 Answers1

3

As per @user2176127 's comment - have you tried this? :

cout << "stop animating!" << endl;
this->animating = false;

std::thread delay_thread(
    [this]() {
        this_thread::sleep_for(chrono::seconds{8});
        this->animating = true;
        std::cout << "start animating!" << std::endl;               
    }
);
delay_thread.detach();
std::cout << "I'm here" << std::endl;

Also note you likely need to wrap the animating member in an std::atomic<>, i.e. if it was bool it now becomes an std::atomic<bool>, so as to ensure your main thread notices the change when it actually happens. (Using volatile won't help.)

einpoklum
  • 118,144
  • 57
  • 340
  • 684