1
\$\begingroup\$

I need a way to delay a function call by 30 seconds on a machine that runs on electric power, not battery (if it matters). I have heard from my colleague not to use sleep, but this post suggests it:

sleep(30) // sleep for 30 sec

Reasons invoked for not using sleep include:

  1. I will violate Single Responsibility Principle.
  2. Abstraction leak, etc.

Not sure why though; I feel it's good because it reduces CPU load and executes important tasks. In the below approach I am trying to just avoid sleep because I am asked not to use it though I am curious to know what a better (best?) approach would be?

void waiting (unsigned int secs)
{
        unsigned int retTime = time(0) + secs;   // Get finishing time.
        while (time(0) < retTime);               // Loop until it arrives.
}
\$\endgroup\$
  • \$\begingroup\$ What platform are you targeting, and how exact does the timing need to be? \$\endgroup\$ – 200_success Feb 20 '17 at 18:41
  • 1
    \$\begingroup\$ What is your colleague's reasoning for avoiding sleep? \$\endgroup\$ – 200_success Feb 20 '17 at 18:42
  • 2
    \$\begingroup\$ Waiting in a spinlock is a bad idea unless the time is very small. If the machine runs on a battery or with poor cooling conditions, chances are that the non sleeping approach will actually cause CPU to throttle performance due to overheat or kill battery very fast. \$\endgroup\$ – Incomputable Feb 20 '17 at 18:47
  • \$\begingroup\$ This question is being discussed in chat. \$\endgroup\$ – 200_success Feb 20 '17 at 20:38
  • \$\begingroup\$ How is sleep a SRP violation or an abstraction leak? \$\endgroup\$ – immibis Feb 21 '17 at 0:25
7
\$\begingroup\$

There is no reason to avoid doing sleep(30);. Your colleague's concerns about the single responsibility principle and abstraction leak are unfounded. sleep() is designed to do exactly what you want, so why not use it? Constantly checking the time in a tight loop is a giant waste of computing power for no advantage at all.

\$\endgroup\$
4
\$\begingroup\$

A mixture of both is more appropriate. sleep may exit even before the amount of seconds is over, so if you want to make sure that you don't exit to soon, you have to check the current time:

void waiting (unsigned int secs)
{
    time_t current = time(NULL);
    const time_t stop = current + secs;

    while(current < stop) {
        sleep(stop - current);
        current = time(NULL);
    }        
}

Note that this solution only needs C features. However, it uses the non-standard function sleep, which might not be available on the target system. Luckily, C++11 and C11 provide their own ways to sleep, e.g.

void waiting (unsigned int secs)
{
    std::this_thread::sleep_for(std::chrono::seconds(secs));
}

This one is guaranteed to sleep at least secs seconds, although it may sleep longer.

Either way, a busy-loop is just wasting resources.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.