Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C Main Loop without 100% cpu

Tags:

#include <stdio.h>

int main() {
  while(!DONE) {
    /* check for stuff */
  }
  return 0;
}

The above code sample uses 100% cpu until DONE is true. How can I implement a program that loops and only terminates when DONE, but which doesn't use 100% cpu? Modern languages use something like App.ProcessMessages or something like that to give the OS the control for the moment and then return to the loop.

I'm new at C, obviously... using latest GCC, linux and windows (a portable solution would be great!)

like image 991
pwseo Avatar asked Aug 03 '09 14:08

pwseo


3 Answers

It depends what you want to do inside this loop.

If you are waiting inside the loop (i.e. if keypressed { do something} then your mechanism will waste system resources giving nothing in return. A faster processor will just make more idle loops. This can be solved by waiting for events Not just sleep, but preferably an event which triggers that something meaningful can be done. For instance, a file operation (stdin is also a file) would be a portable mechanism. This will give way to other applications until data is available. When you become more specific it may be required to dive into semaphores or signals which are often OS dependent. An abstraction layer can resolve this.

If you are doing something useful (i.e. processing a lot of data), then 100% cpu load just means that the processor is used in the most efficient way. You can rely on the operating system to give way to other and possibly higher priority tasks.

Using a function like sleep will lower cpu usage, but your application will be slower. It will require to get a tradeoff between acceptable performance and cpu load. The maximum execution speed will be defined by your sleep parameter, and no longer by the cpu speed. Also, if power is a concern (i.e. battery life time), then this will require the cpu to wakeup (end of sleep period) with no work to be done; i.e. a different waste of system resources.

like image 139
Adriaan Avatar answered Sep 23 '22 01:09

Adriaan


You have several choices:

  1. Use sleep() to force the process to suspend periodically and allow other process to use the CPU
  2. Run at a lower priority level - which will cause the OS to assign less CPU time
  3. Use a mutex or other synchronization object to detect when work is available - which will keep the process from consuming any CPU time unless it is actually doing work
  4. If you get work faster than you can process it - you may still need to use some sort of sleep/priority model to avoid completely consuming the CPU.

Option #2 can be tricky to do in a platform/OS neutral manner. Your best bet is to launch the process and change its priority in the runtime environment.

like image 35
LBushkin Avatar answered Sep 23 '22 01:09

LBushkin


Your two options would be polling, and some kind of event notification.

Polling would be easiest to program -- basically you have your thread sleep for a short while every pass through the loop. This releases the processor to other tasks. The downside is that there will be a delay in your "check for stuff" code -- so if you're sleeping for a second, it might be up to a second before your code detects the condition. Your code here will be easy to port.

The other option is to wait on a POSIX conditional, or Windows event or something like that. Not only will this code be changed, but then the "stuff you're checking" will need to trigger the flag to say it is done. This would be a little less portable code, although there are probably libraries to abstract away the platform. But you'll get immediate results to the event, and no wasted processor time checking for things that aren't there.

like image 36
Clyde Avatar answered Sep 21 '22 01:09

Clyde