我正在写一个服务器,当收到请求时,我将每个动作发送到一个单独的线程。我这样做是因为几乎每个请求都要进行数据库查询。我正在使用线程池库来减少线程的构造/破坏。

我的问题是:对于这样的I/O线程,什么是一个好的截断点?我知道这只是一个粗略的估计,但我们说的是几百吗?成千上万的吗?

我怎么才能算出这个界限呢?


编辑:

感谢大家的回复,似乎我只是要测试一下,以找出我的线程数上限。问题是:我怎么知道我已经达到上限了呢?我到底应该测量什么?


当前回答

我已经编写了大量多线程应用程序。我通常允许由配置文件指定潜在线程的数量。当我针对特定客户进行调优时,我将数值设置得足够高,以至于所有CPU核心的利用率都相当高,但还没有高到遇到内存问题(当时这些是32位操作系统)。

换句话说,一旦你达到某个瓶颈,比如CPU、数据库吞吐量、磁盘吞吐量等,添加更多的线程不会提高整体性能。但在达到这一点之前,请添加更多线程!

请注意,这是假设系统是专门为你的应用程序,你不需要很好地发挥(避免饥饿)其他应用程序。

其他回答

正如帕克斯所说,衡量,而不是猜测。这就是我为DNSwitness所做的事情,结果令人惊讶:理想的线程数比我想象的要高得多,大约15,000个线程才能获得最快的结果。

当然,这取决于很多东西,这就是为什么你必须衡量自己。

在Combien de fils d'exécution ?中的完整测量(仅法语)。

在大多数情况下,您应该允许线程池处理这个问题。如果您发布一些代码或提供更多细节,可能更容易看到是否有某些原因导致线程池的默认行为不是最好的。

你可以在这里找到更多关于如何工作的信息:http://en.wikipedia.org/wiki/Thread_pool_pattern

需要考虑的一件事是,将执行代码的机器上有多少内核。这表示在任何给定时间内可以处理多少线程的硬限制。但是,如果像您的情况一样,线程需要频繁地等待数据库执行查询,那么您可能需要根据数据库可以处理多少并发查询来调优线程。

如果您的线程正在执行任何类型的资源密集型工作(CPU/磁盘),那么您很少会看到超过一到两个的好处,太多会很快降低性能。

“最好的情况”是,当第一个线程完成时,后面的线程将会停止,或者一些线程在资源上有低开销的块,且资源争用低。最坏的情况是您开始折腾缓存/磁盘/网络,并且您的总体吞吐量下降到地板。

一个好的解决方案是将请求放在一个池中,然后从线程池分派给工作线程(是的,避免持续的线程创建/销毁是很好的第一步)。

然后,可以根据概要分析的结果、正在运行的硬件以及机器上可能发生的其他情况调整和缩放此池中的活动线程数。

我认为这有点回避你的问题,但是为什么不把它们分成进程呢?我对网络的理解(从以前模糊的日子里,我根本就没有编写网络代码)是每个传入的连接都可以作为一个单独的进程来处理,因为如果有人在您的进程中做了一些讨厌的事情,它不会破坏整个程序。