【问题标题】:How to find out the optimal amount of threads?如何找出最佳线程数?
【发布时间】:2010-10-29 22:20:59
【问题描述】:

我正计划制作一个具有大量对等网络连接的软件。通常我会为每个连接创建一个自己的线程来发送和接收数据,但在这种情况下,有 300-500+ 个连接,这意味着不断创建和销毁大量线程,我猜这将是一个很大的开销。并且让一个线程按顺序处理所有连接可能会减慢一点速度。 (我不太确定。)

问题是:处理这类问题的最佳线程数是多少?是否有可能在软件中计算它,以便它可以决定自己在没有那么多资源的旧计算机上创建更少的线程,而在新计算机上创建更多线程?

这是一个理论问题,我不想让它依赖于实现或语言。但是我认为很多人会建议“只需使用ThreadPool,它会处理这样的事情”,所以假设它不是.NET 应用程序。 (我可能不得不在旧的 Delphi 项目中使用代码的其他部分,因此语言可能是 Delphi 或 C++,但尚未确定。)

【问题讨论】:

标签: multithreading


【解决方案1】:

了解应用程序在负载下的性能是关键,正如前面提到的分析、测量和重新测试是要走的路。

作为一般指南 Goetz 谈论拥有

线程 = CPU 数量 + 1

对于 CPU 密集型应用程序,以及

CPU 数量 *(1 + 等待时间/服务时间)

对于 IO 绑定上下文

【讨论】:

    【解决方案2】:

    如果这是 Windows(您确实提到了 .Net?),您绝对应该使用 I/O completion ports 来实现它。这是进行 Windows 套接字 I/O 的最有效的方法。在该文档链接中有关于线程池大小的特定于 I/O 的讨论。

    I/O 最重要的属性 完成端口要仔细考虑 是并发值。这 完成端口的并发值 在创建时指定 通过 CreateIoCompletionPort NumberOfConcurrentThreads 参数。 该值限制了 与 完成端口。当总数 与相关联的可运行线程数 完成端口到达 并发值,系统阻塞 任何后续的执行 与之相关的线程 完成端口直到数量 可运行线程低于 并发值。

    基本上,您的读取和写入都是异步的,并且由您可以修改其大小的线程池提供服务。不过还是先试试默认吧。

    the Free Framework 有一个很好的免费示例来说明如何执行此操作。有一些陷阱可以帮助您缩短工作代码。

    【讨论】:

      【解决方案3】:

      您可以在安装时根据 cpu 速度、内核和内存空间进行计算,并在某处设置一个常数来告诉您的应用程序要使用多少线程。想到信号量和线程池。

      就我个人而言,我会将监听套接字与发送套接字分开,并在运行时打开发送套接字,而不是将它们作为守护进程运行;监听套接字可以作为守护进程运行。

      多线程可能会让人头疼,并引入许多错误。最好的办法是让一个线程做一件事并在处理时阻塞以避免不希望的和不可预测的结果。

      【讨论】:

        【解决方案4】:
        1. 使线程数可配置。
        2. 针对一些您希望支持的最常见的特定配置。
        3. 获取良好的性能分析器/检测您的代码,然后使用 1 的不同值对所有不同类型的 2 进行严格测试,直到找到适用于每种配置的最佳值。

        我知道,这似乎是一种不太聪明的做事方式,但我认为在性能方面,通过测试对结果进行基准测试是真正了解它的工作好坏的唯一可靠方法.

        编辑:+1 对上面 paxDiablo 作为评论发布链接的问题。它几乎是同一个问题,并且那里有大量信息,包括 paxDiablo 本人的非常详细的回复。

        【讨论】:

          【解决方案5】:

          每个 CPU 一个线程,处理几个(数百个)连接。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-11-01
            • 2012-06-27
            • 1970-01-01
            • 2010-11-20
            • 2016-09-19
            • 2016-08-03
            • 2021-06-29
            • 2011-02-15
            相关资源
            最近更新 更多