线程非常快地使用了 100% 的 CPU

7

我正在C#中实现一个非常基本的线程:

private Thread listenThread;

public void startParser()
{
    this.listenThread = new Thread(new ThreadStart(checkingData));
    this.listenThread.IsBackground = true;
    this.listenThread.Start();
}

private void checkingData()
{
    while (true)
    {
                
    }
}

我立即遇到了100%的CPU占用率。我想检查是否在while(true)循环内读取传感器数据。为什么会这样呢?

先谢谢你。


我们可以假设while循环中实际上有一些实现,并且它具有某种终止能力吗? - Yuck
1
根据这段代码,获得100%的CPU是正确的。您想要检查传感器数据的时间间隔吗?可能需要相应地使线程休眠。 - CharithJ
5个回答

15

while (true)会让你的CPU不断工作,造成资源浪费。

可以在while循环中添加 Thread.Sleep(X) 让CPU进行休息,之后再进行下一次检查。

同时,看起来你需要一个定时器。

在这里查看其中一个定时器类 http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx

使用定时器时,尽可能使用高的轮询间隔,例如1秒或半秒钟。
你需要在CPU使用率和检查之间能承受的最大延迟之间进行权衡。


嗨,谢谢。但是我该如何等待数据到来呢?我想要不断地检查数据的到来。 - olidev
1
你需要实际检查多频繁?即使让它休眠10毫秒也会产生巨大的影响。 - g.foley
@JoesyXHN - 你的数据来自哪里? - Alex Aza

2

因为你的函数在while块中没有执行任何操作,它占用了CPU,并且实际上从未释放它,所以其他线程无法完成他们的工作。

private void checkingData()
{
    while (true)
    {
        // executes, immediately
    }
}

如果你按照以下方式进行更改,你应该会看到更为合理的CPU占用情况:
private void checkingData()
{
    while (true)
    {
        // read your sensor data 

        Thread.Sleep(1000);
    }
}

2

让你的循环“休眠”一下。它一直在不停地运行,已经累了。至少要让它最终休息一下。


我应该使用 timer.tick 每 1 毫秒而不是使用带有 while 循环和 sleep 的线程吗? - olidev
BAHAHAHAHAHAHAHA!1毫秒!试试100-500毫秒。 - William Mioch

0

你可以使用阻塞队列。从阻塞队列中取出一个项目将会阻塞线程,直到有一个项目被放入队列中。这不会消耗任何CPU。

在 .NET4 中,你可以使用 BlockingCollection http://msdn.microsoft.com/en-us/library/dd267312.aspx

在版本 4 之前的 .NET Framework 中没有阻塞队列。

如果你搜索一下,可以找到许多阻塞队列的实现。

这里是一个实现:

http://www.codeproject.com/KB/recipes/boundedblockingqueue.aspx

顺便问一下,你等待的数据从哪里来?

编辑

如果你想要检查文件,可以使用FileSystemWatcher在线程阻塞的情况下进行检查。

如果你的数据来自外部API且该API不会阻塞线程,那么除了使用Thread.Sleep之外,没有其他方法可以阻塞线程。


如果JoesyXHN需要检查文件、外部API或其他内容,阻塞集合将如何帮助? - Alex Aza
你说得对。如果他想要观看一个文件或者数据来自外部API,那么阻塞集合就无用了。 - Terry Ma
所以我问他数据从哪里来。 - Terry Ma

0
如果您正在轮询某个条件,一定要像其他人建议的那样加入睡眠。我还想补充一点,如果您需要最大的性能,可以使用统计技巧来避免在读取传感器数据时进行睡眠。当您检测到传感器数据连续空闲了10次时,再开始在每次迭代中进行睡眠。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接