我有两个线程。一个线程从串口收集数据,并将其放入数组中,然后添加到并发队列中。另一个线程会实时地绘制出这些数据。每秒钟大约有150个50字节的数据包。
问题在于,当程序运行时,它会消耗大约10%的CPU资源。这是在非常快的I7 Haswell核心上测试的结果。如果在消费线程中添加Thread.Sleep(1),则CPU利用率会降至1%。但是,如果将其设置为Thread.Sleep(2),那么数据包就无法同步了。因此,这不是一种解决方案,如果在较慢的计算机上运行,则可能无法正常工作。
代码很简单。以下是生产者线程:
static void FillQueue(byte[] buffer)
{
dataQueue.Enqueue(buffer);
}
这里是消费者线程:
while (continuePolling)
{
Thread.Sleep(1); //if removed, there is 10% CPU utilization. If higher then packet synchronization is lost.
if (dataQueue.TryDequeue(out result))
{
ProcessPacket(result);
}
}
我觉得这很难理解,因为ProcessPacket方法需要大约0.3毫秒才能执行,每秒调用约10次。
现在我已经尝试使用阻塞集合。以下是生产者代码:
BlockingCollection<byte[]> dataQueue = new BlockingCollection<byte[]>;
public static void addData(buffer)
{
dataQueue.add(buffer);
}
这是消费者
while (dataQueue.TryTake(out result)
{
ProcessPacket(result);
}
完全没有区别!它使用10%的CPU,如果我添加Thread.Sleep(1),它就可以正常工作,但是如果我添加Thread.Sleep(2),就会丢失数据包。 我不明白。每个数据包中有50个字节。就这样。并且它们被生产和消费的速度一样快。 谢谢
BlockingCollection
而不是ConcurrentQueue
,以避免需要使用阻塞的Take
方法调用Thread.Sleep
。 - mjwills