0

现在,我正在一个带有无限循环的新线程中读取外部应用程序的内存

public void ReadMemory()
{
//read memory
Thread.Sleep(10);
}

不幸的是,即使是 1 毫秒的睡眠,我也可以在 1 分钟内完成 60-100 个循环。没有任何睡眠,它是 1000-1500/秒的循环,但它需要很多 CPU。我不敢相信我对此无能为力,所以我在这里问你:P。CPU 使用率可能是一个问题,因为我想在不同的线程中添加更多的后台工作功能(或其他)

有什么东西不会像暂停 10 毫秒那样减少循环的数量吗?

4

3 回答 3

4

不用担心 CPU 使用率。这是一个荒谬的概念。

没有所谓的“运行一点点的代码”或“缓慢运行代码只消耗 25% 的 CPU”之类的东西。

在最低级别,它是一个二进制的东西:你的代码要么运行,消耗它运行的 100% 的内核,要么不运行,在这种情况下它使用 0% 的 CPU。

操作系统向您显示的 CPU 使用率是运行平均值。

所以你需要问的问题不是“我如何在不使用这么多 CPU 的情况下运行我的代码”,而是更简单的“我的代码在不应该运行的时候运行吗?” 如果您希望您的代码运行,那么它至少会暂时使用 100% 的 CPU,这并没有什么问题。

目前还不清楚Sleep()调用在您的应用程序中扮演什么角色。你在等什么?您是否只想在每次迭代之间传递几毫秒?还是您在等待某个特定事件的发生?

无论如何,当您调用 时Sleep(10),您不会将线程挂起 10 毫秒。您将其暂停至少10 毫秒。您现在告诉操作系统将线程放入睡眠队列,一旦 10 毫秒过去,线程应该被认为有资格再次执行。但这仍然取决于操作系统来安排你的线程,这可能需要另外 10 毫秒(或更多或更少,取决于各种因素)

在 Windows 上,Sleep(0)这是一种特殊情况,您可以进行试验。它并没有实际挂起您的线程,而是简单地告诉操作系统该线程已完成其当前时间片,允许其他线程/进程执行,但不会让您的线程进入睡眠状态:它仍然有资格在下次上下文切换时被调度发生。因此,如果目标只是确保其他线程/进程有机会运行,那么调用Sleep(0)可能是一种方法。

另一种方法是忽略这个问题,并相信操作系统知道如何安排进程(这是一个非常安全的假设。除非你真的看到你的其他后台进程正在被饿死,否则不要担心这个。他们最可能不会)。

最后,当然,您可以设置线程和进程优先级,向操作系统提示它应该更喜欢调度哪些线程。如果你给这个线程一个低优先级,它只会在没有更高优先级的线程可用时被调度,确保你不会饿死其他线程。

于 2012-07-14T14:40:16.157 回答
1

如果您只是偶尔这样做,而不是每次迭代都睡觉。

就像是 :

public class Reader
{
    private static int count= 0;

    public void ReadMemory()
    {
        //read memory

        // Sleep every 501 iterations
        if (Reader.count++ == 500)
        {
            Thread.Sleep(1);
            Reader.count  = 0;
        }
    }
}

如果您以每秒大约 1000 次迭代的速度运行并且需要 1 秒来执行切换,那么这意味着您将以全功率运行半秒,然后减速一秒钟,然后返回全功率,这平均每秒迭代 333 次。

显然,您可以尝试使用 500 以外的值进行试验。

于 2012-07-14T15:38:05.177 回答
1

线程被设计为尽可能多地消耗 CPU 时间,除非其他线程需要该 CPU 时间。 如果您只是想释放线程以便 CPU 可以执行其他任务,请不要这样做。Windows 将根据需要自动将马力分配给任何其他线程。

于 2012-07-14T14:27:53.023 回答