繁体   English   中英

C# - 使用Thread.Sleep()让我的循环每秒运行几百次

[英]C# - using Thread.Sleep() to get my cycle run several hundred times per second

我正在开发一个分析实时财务数据的应用程序。 目前我的主要计算周期有以下设计:

long cycle_counter=0;
while (process_data)
{
  (analyse data, issue instruction - 5000 lines of straightforwasrd code with computations)
  cycle_counter++;
  Thread.Sleep(5);
}

当我在我的笔记本(一个Core i5)处理器上运行这个应用程序时,循环每秒运行200-205次 - 这是一种预期的(如果你不打扰为什么它每秒运行超过200次)。

但是当我在具有2个6核Xeon处理器和24 GB快速RAM的“真实”工作站上部署应用程序,并且在大约3秒内加载Win7时,应用程序每秒运行大约67次。

我的问题是:

  • 为什么会这样?

  • 在这种情况下,如何影响每秒的运行次数?

  • 有没有更好的解决方案,每秒运行200-1000次循环? 我现在正在考虑删除Thread.Sleep()(我在这里使用它的方式受到了很多批评)。 有12个内核,我只使用一个内核就可以解决这个问题。 但是我的解决方案有一些缺点吗?

谢谢你的想法。

你正在采取的方法从根本上被打破了。 轮询策略通常是一种不好的方法,并且任何时候你出于“我想将剩下的时间片还给操作系统”之外的其他原因进行睡眠时,你可能做错了什么。

解决问题的更好方法是:

  • 创建未处理工作的线程安全队列
  • 创建一个将新工作放入队列的线程
  • 创建n个线程,将工作从队列中取出并完成工作。 n应该是你减去一个CPU的数量。 如果你有超过n个线程,那么至少有两个线程会占用CPU时间,这会让它们变得更慢!
  • 工作线程什么也不做,只是坐在一个循环中,将工作从队列中取出并完成工作。
  • 如果队列为空,则“取出工作”
  • 当新工作到达时,其中一个被阻止的线程将被重新激活。

如何使用这些属性构建队列是一个着名的问题,称为生产者/消费者问题。 关于如何执行阻塞生产者 - 消费者队列的任何许多实现,有很多文章。 我建议找一个现有的调试版,而不是试着写自己的; 做得对可能很棘手。

睡眠的分辨率由当前的计时器滴答间隔决定,通常为10或15毫秒,具体取决于Windows的版本。 但是,可以通过发出timeBeginPeriod命令来更改此设置。 看到这个答案

Windows不是RTOS(实时操作系统),因此您无法准确确定线程何时恢复。 Thread.Sleep(5)真的意味着“在5ms之后叫醒我”。 实际的休眠时间由特定硬件决定,主要由系统负载决定。 您可以尝试通过以更高优先级运行应用程序来解决system load问题。

顺便说一句, System.Threading.Timer是一种更好的方法(上面的评论仍然适用)。

检查计时器的实际频率 :许多硬件计时器具有实际分辨率

  65536 ticks per hour = 65536 / 3600 = 18.204 ticks per second 

所谓的“18.2”常数,这就是实际定时器的分辨率为1 / 18.2 = 55 ms的原因 ; Sleep(5)的情况下,它意味着可以是Sleep(0)Sleep(55)具体取决于向上舍入。

不确定这是最好的方法,但另一种方法。
尝试BlockingCollection,你在生产者中所做的只是添加和睡眠。
然后,消费者可以选择在需要时全职工作。
这仍然无法解释为什么更高功率的PC运行更少的周期。

您可以平均每秒运行200次循环吗?

var delay = TimeSpan.FromMillseconds(5);
while (process_data) {
    Console.WriteLine("do work");
    var now = DateTime.Now;
    if (now < nextDue) 
        System.Threading.Thread.Sleep(nextDue - now);
    nextDue = nextDue.Add(delay);
}

使用这种技术,你的循环会有点磕磕绊绊,但它平均应该没问题,因为代码既不依赖于Sleep的分辨率也不依赖于DateTime.Now的分辨率。

您甚至可以将此方法与Timer结合使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM