CPU友好的无限循环友好、CPU

2023-09-02 11:56:46 作者:喂你吃翔

写一个无限循环很简单:

 ,而(真){
    //这里添加任何中断条件
}
 

但是,这将毁掉CPU的性能。该执行线程将采取尽可能多的从CPU的电源。

什么是降低了CPU的影响,最好的方法是什么? 添加一些 Thread.sleep代码(N)应该做的伎俩,但设置较高的超时值睡眠()方法可指示无响应的应用程​​序到操作系统。

比方说,我需要在控制台应用程序执行任务,每分钟左右。 我需要保持主要()在无限循环运行时计时器将触发,会做这项工作的事件。我想保持主要()与CPU的影响最小。

你认为什么方法。 睡眠()可以是好的,但正如我前面提到的,这可能表示无响应的线程操作系统。

以后编辑:

我要更好地解释什么,我在寻找:

我需要一个控制台应用程序而不是Windows服务。控制台应用程序可以模拟在Windows Mobile 6.x的系统框架精简版Windows的服务。

我需要一种方法来保持应用程序活着,只要Windows Mobile的设备正在运行。

我们都知道,在控制台应用程序运行,只要它的静态main()函数运行,所以我需要一种方法来prevent main()函数退出。

不装Win11吗 Win10对你的CPU可能不够友好

在特殊情况下(如:更新应用程序),我需要请求应用程序停止,所以我需要无限循环,并测试了一些退出条件。例如,这也就是为什么到Console.ReadLine()是没有用的我。没有退出条件检查。

对于上述情况,我还是希望main()函数的资源尽可能友好。让asside来检查退出条件的函数的指纹。

解决方案

要避免无限循环简单地使用的WaitHandle 。让程序可以从外面的世界退出使用的EventWaitHandle 有一个唯一的字符串。下面是一个例子。

如果你开始它的第一次,它简单的打印出一条消息,每10秒。如果您在此期间启动程序的第二个实例会通知其他进程正常退出,并立即退出本身也。 CPU使用率这种方法:0%

 私有静态无效的主要(字串[] args)
{
    //创建一个IPC等待一个唯一的标识符处理。
    布尔createdNew;
    VAR的WaitHandle =新的EventWaitHandle(假,EventResetMode.AutoReset,CF2D4313-33DE-489D-9721-6AFF69841DEA,出createdNew);
    VAR信号= FALSE;

    //如果手柄已经在那里了,告知对方进程退出本身。
    //之后我们还会死亡。
    如果(!createdNew)
    {
        日志(通知其他进程停止。);
        waitHandle.Set();
        日志(线人退出。);

        返回;
    }

    //启动另一个线程做一些事情每10秒。
    VAR定时器=新的定时器(OnTimerElapsed,空,TimeSpan.Zero,TimeSpan.FromSeconds(10));

    //等待,如果有人告诉我们,死亡或做每五秒钟别的东西。
    做
    {
        信号= waitHandle.WaitOne(TimeSpan.FromSeconds(5));
        // TODO:东西,如果需要的东西。
    }而(!信号);

    //与拦截器上面的循环也可以通过无尽的服务员更换
    //waitHandle.WaitOne();

    日志(得到的信号杀死我自己。);
}

私有静态无效日志(字符串消息)
{
    Console.WriteLine(DateTime.Now +:+消息);
}

私有静态无效OnTimerElapsed(对象状态)
{
    日志(计时器经过。);
}
 

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:

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

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

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.

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.

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.

解决方案

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