CPU friendly infinite loop

前端 未结 11 1916
心在旅途
心在旅途 2020-12-04 09:15

Writing an infinite loop is simple:

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

But this will trash the CPU performance. This ex

11条回答
  •  庸人自扰
    2020-12-04 09:39

    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.");
    }
    

提交回复
热议问题