【问题标题】:Creating background/throttled thread创建后台/节流线程
【发布时间】:2009-11-02 11:35:23
【问题描述】:

我正在尝试在“后台”线程中执行一段长时间运行的代码,“后台”是指低优先级线程而不是 .NET 背景术语。我创建了一个线程,将其优先级设置为最低,如果没有其他线程在运行,仍然使用 100% CPU。当我手动调用 Thread.Sleep(1) 但我不想更改我的代码并且通过 Thread.Sleep 控制 CPU 利用率时,情况会有所改善。

我想要某种方式来执行一段代码,该代码将被限制以确保 CPU 使用率在 5%-10%。另外我不想过多地更改代码(它非常复杂)。

有可能吗?

【问题讨论】:

  • 如果没有其他线程在使用 CPU,那这有什么关系呢?
  • 5% 到 10% 的 CPU 使用率除了给你带来好感之外还有什么?完成任务将花费类似数量的周期,只是延长了更长的时间。另请注意,就能耗而言,少量高负载(在现代 CPU 上)要好得多,因为 CPU 可以更早地进入低功耗状态——这在便携式机器或服务器场中可能很重要。
  • 您的正确率可能在 5%-10% 左右——这可能是我的人性。就像我说的,我不介意这个后台同步任务被拉伸 10-20 倍——这不是必需的。但是其他线程的高可用性和快速执行是。代码是在服务器上运行的,只要代码满足业务需求,我其实并不担心能耗问题。
  • 我说得不准确 - 有另一个线程正在耐心等待客户端请求,大部分时间什么都不做。但是当请求到来时,它必须立即执行并且它是 CPU 密集型的(分布在多个线程中),尽管相对较短(0.1 - 0.2 秒)。当请求到来并延迟其执行时,我不能让另一个线程以 100% CPU 运行。

标签: c# .net multithreading


【解决方案1】:

这听起来有点像您需要解决错误的问题 - 而不是尝试将线程限制为设定的 CPU 使用率(我不确定您是否可以这样做),线程正在执行的操作是否有问题/它是怎么做的?也就是说,如果它使用 100% 的 CPU,那么您是否可以对该逻辑采取任何措施来降低其 CPU 密集度?

您可能会发现您可以重新设计/优化它,以防止它首先变得如此密集,从而从根本上解决问题。

更新:使用计时器定期读取外部源。一个很好的参考是here。您将解决 CPU 使用率高的根本原因,方法是不持续检查这些来源,而是定期检查(例如,即使您每 15 秒检查一次,也会产生巨大的影响)

【讨论】:

  • 我可以添加一些 Thread.Sleep 但这有点乱。该进程本身从外部源读取数据并重新填充内存缓存。直到我读取数据才知道数据何时更改,因此“后台”进程不断枚举/读取所有数据源并刷新内存缓存。数据不必是最新的(我的意思是几分钟的延迟是可以接受的),但它需要高度可访问(因此数据总是从内存缓存中提供)。
  • 这是真正的问题 - 不断读取数据源。最好的解决方案是仅定期执行此操作,您可以使用计时器来执行此操作。我将更新我的答案以包含参考。
  • 谢谢 AdaTheDev - 我会阅读引用的文章并尝试将代码分成更易于管理的块。
【解决方案2】:

也许您应该让您的“后台”线程检查在高优先级线程工作时设置的共享布尔值,然后等到它取消设置。

【讨论】:

    【解决方案3】:

    设置线程优先级不是绝对的事情。它与程序中的其他线程有关。

    将线程优先级设置为 Normal 将意味着它获得处理器时间的相等“份额”(与其他 Normal 线程)。

    将优先级设置为低(或最低)意味着与同一程序中的普通线程相比,它获得的处理器时间更少,而将其设置为高(或最高)意味着它获得更多。

    如果只有一个线程,那么无论您设置的优先级如何,它都会获得所需的 CPU。

    正如 AdaTheDev 所说,如果它使用 100% 的 CPU,那么问题在于您的算法,而不是 Windows 如何将处理器时间分配给线程。

    【讨论】:

      猜你喜欢
      • 2017-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多