Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CPU friendly infinite loop

Writing an infinite loop is simple:

while(true){     //add whatever break condition here } 

But this will trash the CPU performance. This execution thread will take as much as possible from CPU's power.

What is the best way to lower the impact on CPU? Adding some Thread.Sleep(n) should do the trick, but setting a high timeout value for Sleep() method may indicate an unresponsive application to the operating system.

Let's say I need to perform a task each minute or so in a console app. I need to keep Main() running in an "infinite loop" while a timer will fire the event that will do the job. I would like to keep Main() with the lowest impact on CPU.

What methods do you suggest. Sleep() can be ok, but as I already mentioned, this might indicate an unresponsive thread to the operating system.

LATER EDIT:

I want to explain better what I am looking for:

  1. I need a console app not Windows service. Console apps can simulate the Windows services on Windows Mobile 6.x systems with Compact Framework.

  2. I need a way to keep the app alive as long as the Windows Mobile device is running.

  3. We all know that the console app runs as long as its static Main() function runs, so I need a way to prevent Main() function exit.

  4. In special situations (like: updating the app), I need to request the app to stop, so I need to infinitely loop and test for some exit condition. For example, this is why Console.ReadLine() is no use for me. There is no exit condition check.

  5. Regarding the above, I still want Main() function as resource friendly as possible. Let asside the fingerprint of the function that checks for the exit condition.

like image 433
Adi Avatar asked Sep 13 '11 12:09

Adi


People also ask

Can an infinite loop break your computer?

No. Unless the application has left behind execution artifacts (such as other zombie processes which happen to loop too), nothing will happen (after the execution of the process stops, the operating system reclaims all the resources it held).

How CPU is protected from an infinite loop?

To avoid a process running forever, whenever the operating system kernel allows a process to execute (by branching to its code), it first programs the clock to send an interrupt at a certain time in the future, allowing the program to run uninterrupted only for a time slice.

Is it good to use infinite loop?

Infinite loops are useful if you want your script (or part of the code) to run endlessly, until a specific action is taken. Especially, when there can be more than one action that stops your script or block of code from working. In event-based programming paradigm endless loops are very common.

What will happen if I run an infinite loop?

An infinite loop is a piece of code that keeps running forever as the terminating condition is never reached. An infinite loop can crash your program or browser and freeze your computer. To avoid such incidents it is important to be aware of infinite loops so that we can avoid them.


2 Answers

You can use System.Threading.Timer Class which provides ability to execute callback asynchronously in a given period of time.

public Timer(     TimerCallback callback,     Object state,     int dueTime,     int period ) 

As alternative there is System.Timers.Timer class which exposes Elapsed Event which raises when a given period of time is elapsed.

like image 24
sll Avatar answered Oct 07 '22 23:10

sll


To avoid the infinity loop simply use a WaitHandle. To let the process be exited from the outer world use a EventWaitHandle with a unique string. Below is an example.

If you start it the first time, it simple prints out a message every 10 seconds. If you start in the mean time a second instance of the program it will inform the other process to gracefully exit and exits itself also immediately. The CPU usage for this approach: 0%

private static void Main(string[] args) {     // Create a IPC wait handle with a unique identifier.     bool createdNew;     var waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, "CF2D4313-33DE-489D-9721-6AFF69841DEA", out createdNew);     var signaled = false;      // If the handle was already there, inform the other process to exit itself.     // Afterwards we'll also die.     if (!createdNew)     {         Log("Inform other process to stop.");         waitHandle.Set();         Log("Informer exited.");          return;     }      // Start a another thread that does something every 10 seconds.     var timer = new Timer(OnTimerElapsed, null, TimeSpan.Zero, TimeSpan.FromSeconds(10));      // Wait if someone tells us to die or do every five seconds something else.     do     {         signaled = waitHandle.WaitOne(TimeSpan.FromSeconds(5));         // ToDo: Something else if desired.     } while (!signaled);      // The above loop with an interceptor could also be replaced by an endless waiter     //waitHandle.WaitOne();      Log("Got signal to kill myself."); }  private static void Log(string message) {     Console.WriteLine(DateTime.Now + ": " + message); }  private static void OnTimerElapsed(object state) {     Log("Timer elapsed."); } 
like image 142
Oliver Avatar answered Oct 07 '22 23:10

Oliver