【问题标题】:Threads with low priority prevents other threads with normal priority from execution低优先级线程阻止其他具有正常优先级的线程执行
【发布时间】:2020-07-09 06:57:47
【问题描述】:

我们发现几个 CPU 密集型查询意味着我们的 API 服务器不再响应简单的请求。 API 服务器是一个带有 kestrel 的 .net 核心应用程序,它在 Kubernetes 集群中执行。 但是,如果应用程序在 Windows 或 Linux 主机上运行,​​则任务优先级似乎可以完美运行。即使有数十个 CPU 密集型请求,该服务也会响应。所以看来Docker环境和宿主环境还是有很大区别的。

我将此 API 方法用于测试目的:

public void SimulateHighCpuLoad()
{
    var previousPriority = Thread.CurrentThread.Priority;

    try
    {
        Thread.CurrentThread.Priority = ThreadPriority.Lowest;

        var until = DateTime.Now.AddSeconds(30);
        var num = 0L;
        var random = new Random();

        // do senseless work for 30 seconds
        while (DateTime.Now < until)
        {
            num = (random.Next() + Environment.TickCount + num) % (random.Next(10000) + 1);
            num *= num++;
        }
    }
    finally
    {
        Thread.CurrentThread.Priority = previousPriority;
    }
}

我的目标是降低 CPU 密集型方法的优先级,以便应用程序始终可以响应其他请求(例如 LivenessProbe 的健康请求)。 Thread.Priority 似乎在 docker 环境中被完全忽略了

【问题讨论】:

  • 增加线程池的大小,使用SemaphoreSlim来限制CPU繁重任务的数量....这样一些线程可以用来处理I/O?
  • 谢谢@JeremyLakeman。我检查了主机环境和 kubernetes 环境的线程池最小/最大大小。值相等。 ThreadPool.GetAvailableThreads 始终 > 30,000。
  • 为环境分配了多少 CPU?
  • stackoverflow.com/a/51998044/34092 可能会提供帮助。
  • 集群部署在哪里(云,本地)?命名空间/集群级别是否有任何资源限制?

标签: c# multithreading docker kubernetes .net-core


【解决方案1】:

根据this forum thread,我们并不是唯一有这个问题的人。 线程调度在 Docker 容器(或 K8s 集群)中的工作方式似乎完全不同。

我们尝试了很多,并且能够通过混合限制和Thread.Sleep(0)来解决问题。

请注意以下有关 Thread.Sleep 的文档

如果 millisecondsTimeout 参数的值为零,则线程 将其时间片的剩余部分交给任何相等的线程 准备运行的优先级

没有Thread.Sleep(0),CPU 密集型线程会导致没有其他线程被处理。也没有调用计时器。在 Docker 容器中设置低线程优先级是无效的。

【讨论】:

    猜你喜欢
    • 2014-11-26
    • 2011-06-25
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 2014-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多