5

I have to call a function every X seconds to show the progress of a long running function, but i want to drop the notification if the function ends before the next tick of the progress update. I just recently started using C++11 and i don't know if there is a way to achieve this using proper c++11 syntax/objects.

Basically, I am trying to figure out if there is a way to access the same features as those exposed by the posix functions timer_create and timer_delete using the C++11 threads and async functions.

I did find this question "How to create timer events using C++ 11?", which covers almost everything i need but i couldn't figure out if there's a way to stop the async call once it is "submitted".

Is this possible now in C++11?

Community
  • 1
  • 1
Carlos
  • 183
  • 9
  • 1
    Maybe a timed lock, e.g. [`condition_variable::wait_for`](http://en.cppreference.com/w/cpp/thread/condition_variable/wait_for)? – dyp Jun 11 '14 at 19:55

1 Answers1

6

Introduction

The simple solution is to make it so that the timer set to execute f in N time-units can potentially sleep for N time-units, but if something interrupts the sleep we should not execute the task f.

The usage of std::condition_variable can solve this issue with ease, relying on the member-function wait_for. This function will return false if the function didn't receive an interrupt, and true if it did.

pending sample implementation

Community
  • 1
  • 1
Filip Roséen - refp
  • 62,493
  • 20
  • 150
  • 196
  • Is there no interruptible sleep? In most APIs, this is accomplished via waiting for the cancellation event with a timeout equal to the desired sleep interval. – Ben Voigt Jun 11 '14 at 20:00
  • @BenVoigt ah good point, of course `std::condition_variable::wait_for` can be used in this way, set it to sleep for *N* *time-units*, if interrupted; don't execute task. I'll write a sample implementation to add to the answer. – Filip Roséen - refp Jun 11 '14 at 20:02
  • @BenVoigt IIRC `boost::thread` supports this, but not `std::thread` – dyp Jun 11 '14 at 20:23
  • I see your point and I guess it certainly will work. What i don't like is that this is similar to a busy waiting loop (of course, is a lot lighter because you will be sleeping most of the time) and i have to actually write the logic for the timer to keep working or stop. I liked the timer_create/timer_delete api because i delegate completely the timer implementation/interruption to the timer itself. Although, maybe i'm being just too lazy :P – Carlos Jun 11 '14 at 20:26
  • The overload of `condition_variable::wait_for` that returns a `bool` takes a Predicate, and returns the result of this predicate. The other overload w/o predicate doesn't ignore spurious unblocking. – dyp Jun 11 '14 at 20:26
  • 3
    [Sample implementation](http://coliru.stacked-crooked.com/a/8804fee86d99a1e5 "Live at Coliru"). – Casey Jun 11 '14 at 21:31
  • @Casey I'm currently on my phone, had to rush out the house before I had the chance to post my sample implementation. As soon as I'm at a computer I'll add it. /F – Filip Roséen - refp Jun 11 '14 at 21:32
  • @Casey Why not `wait_for`? – dyp Jun 11 '14 at 21:44
  • @dyp to keep the intervals constant(-ish) regardless of the processing time for the function and queueing delay from the OS. – Casey Jun 11 '14 at 21:46
  • @Casey [According to cppreference](http://en.cppreference.com/w/cpp/thread/condition_variable/wait_for), this should be what `wait_for` does. -- Btw, you should have compiled that with CLANG ;) – dyp Jun 11 '14 at 21:47
  • @dyp It depends whether you want your function to execute every X seconds, or have a delay of X seconds between the completion and initiation of function calls. I think the "every X seconds" semantic is more generally applicable (proof left to the reader). – Casey Jun 11 '14 at 21:48