Reputation: 301
I have a program with a connections processing thread that has a loop. The problem is that the loop runs too fast and consumes 100% CPU core.
I tried putting a std::this_thread::sleep_for(std::chrono::milliseconds(1));
(or similar) at the end if there are no clients(obviously the problem still exists when there are clients), it does solve the CPU hogging, but it also introduces delay to responding to new connections. The sleep is unreliable and can't be too small usually results in > 1ms. And if the sleep is small it doesn't really result in efficient sleeping anyway (1-3% CPU core consumption).
What is a good way to deal with it?
Upvotes: 1
Views: 231
Reputation: 40100
Active waiting is rarely a good idea. it is typically a better approach to delegate the wait to the system and be awaken whenever an event occurs.
On Linux systems, poll()
does exactly this:
#include <poll.h>
// ...
::poll(&fds, nfds, timeout);
Waits (block) timeout
milliseconds for an event to occur on any file descriptor of fds
.
As an alternative for not-related-to-file-descriptor cases, I'd use pthread_cond_wait()
and pthread_cond_signal()
. Those work with a mutex and a condition:
pthread_cond_wait(&cond, &mutex)
unlocks mutex
and immediately put the thread to sleep until cond
is met (signaled), but then it reacquires the mutex.
pthread_cond_signal(&cond)
signals all threads waiting on cond
that a condition might have changed.
A typical usage would be:
worker thread:
::pthread_mutex_lock(&mutex);
while (condition == false) {
::pthread_cond_wait(&cond, &mutex); // passive wait
}
// this part is only invoked when:
// - condition is true
// - mutex has been acquired
::pthread_mutex_unlock(&mutex);
thread handling connection/deconnection:
::pthread_mutex_lock(&mutex);
// add/remove clients
::pthread_cond_signal(&cond);
::pthread_mutex_unlock(&mutex);
See:
Upvotes: 2