6

I would like to write some code that wakes up on (or sleep until) some event.

I have a piece of code that sleeps until some event happens, such as when alarmed by a clock.

Pseudo code:

int main() {
  TimePoint someTp("3PM");
  std::this_thread::sleep_until(someTP);
}

This is my current implementation, but this hogs about 10% of my CPU power. I think my design is flawed, is there any better solution for this? Many thanks in advance!

will
  • 589
  • 1
  • 7
  • 15

3 Answers3

8

The problem is in the implementation of std::this_thread:sleep_until(..) which calls sleep_for(..), which calls nanosleep().

(See the gnu sources, line 271.)

See the following Stackoverflow questions:

You don't appear to need the high resolution of nanosleep(). You might write your own solution with a permissive open source license, and call sleep() instead of nanosleep().

If you do need sub-second resolution, I recommend the technique of calling select() rather than nanosleep(). select() is designed to block very efficiently for sub-second delays, and the timeout parameter is respected accurately enough by most operating systems that it is useful for sub-second timing while yielding the CPU.

You can even create a socket for the purpose of passing to select(), in theerror_fds parameter, where the socket can be used as a cross-thread "signal" when it is passed to close() and becomes an "error" state socket.

Community
  • 1
  • 1
Heath Hunnicutt
  • 18,667
  • 3
  • 39
  • 62
3

A better solution would be using an event driven library such as Boost.Asio or libevent rather than sleeping for some duration.

robert
  • 33,242
  • 8
  • 53
  • 74
Sam Miller
  • 23,808
  • 4
  • 67
  • 87
1

A simple implementation can be to use a Semaphore.

Keep your worker thread blocked on a semaphore and signal the semaphore from another thread where the alarm clock event occurs.

void* workerThread(void*) 
{
     TimePoint someTp("3PM");
     sem_Wait();    //Thread remains blocked here
}

void timercallback()
{
    sem_post(); //Signals worker thread to move ahead

}
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • +1 [Always prefer a semaphore to a busy wait](http://randomascii.wordpress.com/2012/06/05/in-praise-of-idleness/). – Laurent Couvidou Jun 10 '12 at 20:57
  • Waiting idle is certainly better than busy waiting (thanks for the link to my blog post), but I'm not sure what a semaphore achieves here. You have a timercallback() which somehow (you don't say how) is called when the time expires. Why not just run your code in the callback? There may be a reason but it isn't described. That is, in your sample solution the important detail (how to schedule a timercallback) is omitted. Also, thankfully, the OP never suggested busy waiting. – Bruce Dawson May 13 '15 at 00:26