【问题标题】:C# Maximum Number of Threads [duplicate]C#最大线程数[重复]
【发布时间】:2015-07-09 18:36:24
【问题描述】:

我刚开始使用线程,很快我就遇到了一个非常常见的问题,即多少线程太多了?
在做了一些研究之后,我更加困惑了。

任务
我有 16 个内核和一个生成 1000 个对象的应用程序,尽管构造参数是一致的。根据 msdn 文档和 Maximum number of threads,创建 1000 个线程通常会产生巨大的开销,从而破坏多线程的性能优势。此外,我必须保持在 3.5 NET 32 位限制 (Maximum number of threads in a .NET app?) 内。

问题 1
有这样一个单方面的任务,是否可以在计算机上创建比内核更多的线程? .NET 在那里优化了一些东西吗?我应该使用的最大线程数是多少?

问题 2
有没有一个简单漂亮的解决方案,除了用有限的资源排队?类似于信号量的东西,我创建了所有 1000 个线程,但立即停用线程以便不分配默认线程堆栈?

【问题讨论】:

  • 线程池是一个有用的概念。
  • 你不应该创建那么多线程,创建与核心数量一样多的线程,并重用线程来完成多个任务。
  • 您的问题缺少的是您认为线程的作用。为什么你认为创建 1000 个对象需要 1000 个线程?
  • 第一个问题有很好的现有副本。第二个问题(实际上不应该在同一篇文章中提出......)此时非常广泛,不太可能得到具体答案 - 无论如何,请考虑将其作为单独的问题提交,并附上指向该问题的链接并澄清你到底是什么希望用多线程进行优化。

标签: c# multithreading


【解决方案1】:

是的,您可以(并且可能应该)创建比内核更多的线程,因为操作系统调度程序中断以在活动线程之间进行交换,即使没有其他等待那个核心。但是,您也不想创建 1000 个单独的线程。相反,创建多个线程并在它们之间分配工作,以便每个线程处理完整作业中的多个项目。

我发现一个好的经验法则是每个逻辑核心使用两个线程(这会计算超线程核心......如果您有一个 8 核 CPU 和 16 个逻辑核心的超线程,则创建 32 个线程)。这个想法是您希望尽可能少的调度程序中断/上下文交换,但同时让所有核心都忙于主要处理您的任务。鉴于调度程序中断仍然发生,即使逻辑核心上没有其他活动,该核心有两个活动线程意味着调度程序很可能只是从您的程序中放入空闲线程。即使该内核的其他内容处于活动状态,它现在仍然可能是您选择执行的线程。高于此值可能会鼓励更多不必要的上下文切换并损害性能。

简短的版本是每个内核的第二个线程的成本很低(因为上下文切换仍然发生),但回报可能很高(整个调度程序块,其中 cpu 正在处理您的应用程序而不是其他东西)。随着您为每个内核添加更多线程,您开始增加成本并降低潜在收益。

但这只是我(非常有限)的经验。它非常泛化了,而且不仅仅是一个起点。您确实需要概要分析您的应用在不同线程数下的表现,以了解如何对其进行调整以获得最佳性能。

最后,在.Net 世界中,值得一提的是ThreadPoolasync Tasks。这不是了解这些主题的完整教程的最佳地点,但阅读它们非常值得您花时间。

【讨论】:

    【解决方案2】:

    是否可以在计算机上创建比内核更多的线程?

    是的,这是可能的。

    .NET 是否在其中进行了优化? 我应该使用的最大线程数是多少?

    实际上,在 99.99% 的情况下,您不应该关心线程数,因为......在 99.99% 的情况下,您不得手动创建线程。如果您必须保留在 .NET 3.5 中,请改用 ThreadPool。如果您的版本是 4.0 或更高版本,请使用 tasks

    有没有一个简单漂亮的解决方案,除了用有限的资源排队?

    事实上,没有。你不能跳过物理上可用的资源,这是瓶颈。

    【讨论】:

      【解决方案3】:

      基本上,当您赚得更多时,您从新线程中获得的性能百分比越来越少。 10 个线程的运行速度并不比 1 个线程快 10 倍。此外,当您运行的线程数多于内核数时,您不会从中获得任何有意义的任何东西

      经验法则是对性能要求高的代码使用线程,让它在后台而不是 UI 线程上运行,这样可以避免阻塞 UI 响应。如果您想优化已经是非 UI 块的代码,那么您可以查看目标机器上的内核数量并创建更多线程来帮助繁重的算法(如果有意义的话)。请记住,调试和维护和编写多线程代码要困难得多。

      因此,仅在实验和学习时才这样做,否则仅在您确实需要为应用程序注入一些额外功能时才这样做。

      答案 1: 是的,可以创建比内核更多的线程,但它的意义几乎为零。

      答案 2: 不要创建 1000 个线程来创建 1000 个对象!这不漂亮

      【讨论】:

        猜你喜欢
        • 2016-05-10
        • 2019-12-09
        • 2010-12-16
        • 1970-01-01
        • 2011-04-20
        • 1970-01-01
        • 2018-10-14
        相关资源
        最近更新 更多