Best way to implement busy loop?
What is the best way to implement the busy loop ? correct me if i am wrong ?
while (1);开发者_StackOverflow中文版 // obviously eats CPU.
while (1) { sleep(100); } // Not sure if it is the correct way ?
To do an infinite wait, for a signal (what else) there is the pause()
system call. You'll have to put it in a loop, as it returns (always with -1 and errno set to EINTR) every time a signal is delivered:
while (1)
pause();
As a curious note, this is, AFAIK the only POSIX function documented to always fail.
UPDATE: Thanks to dmckee, in the comments below, sigsuspend()
also fails always. It does just the same as pause()
, but it is more signal-friendly. The difference is that it has parameters, so it can fail with EFAULT
in addition to EINTR
.
Busy loop is loop that never blocks and continuously checks some condition. Small sleep is good enough to avoid 100% cpu usage.
The best way to implement busy wait is to not implement it. Instead of it you can use blocking calls or callbacks.
Linux has had the (POSIX 1.g) pselect for some time now. If you are using signal handlers or user-defined signals, I think this is worth investigating. It also addresses some subtle race conditions that manifest in other approaches.
I know you mentioned the 'busy loop', but I think a 'blocking loop' is what you're after.
How to prevent it from being optimized away with data dependencies
First of course, you should only use busy loops if you have very good reason to not use non-busy ones, which are generally more efficient, see: https://codereview.stackexchange.com/questions/42506/using-a-for-loop-or-sleeping-to-wait-for-short-intervals-of-time
Now, focusing only on busy loops, if you just write something like:
while (1);
or:
for (unsigned i = 0; i < 100; i++);
then both of those can be optimized away as mentioned at: Are compilers allowed to eliminate infinite loops?
For this reason, as explained in detail at: How to prevent GCC from optimizing out a busy wait loop? I would write them as:
while (1) asm("");
or:
for (unsigned i = 0; i < 100; i++) {
__asm__ __volatile__ ("" : "+g" (i) : :);
}
精彩评论