How not to hog CPU while waiting for some event?
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_threa开发者_如何学Pythond::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!
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:
- nanosleep high cpu usage? (Linux high-cpu issue calling nanosleep.)
- boost::this_thread::sleep() vs. nanosleep()?
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.
A better solution would be using an event driven library such as Boost.Asio or libevent rather than sleeping for some duration.
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
}
精彩评论