我正在写一个服务器,当收到请求时,我将每个动作发送到一个单独的线程。我这样做是因为几乎每个请求都要进行数据库查询。我正在使用线程池库来减少线程的构造/破坏。
我的问题是:对于这样的I/O线程,什么是一个好的截断点?我知道这只是一个粗略的估计,但我们说的是几百吗?成千上万的吗?
我怎么才能算出这个界限呢?
编辑:
感谢大家的回复,似乎我只是要测试一下,以找出我的线程数上限。问题是:我怎么知道我已经达到上限了呢?我到底应该测量什么?
我正在写一个服务器,当收到请求时,我将每个动作发送到一个单独的线程。我这样做是因为几乎每个请求都要进行数据库查询。我正在使用线程池库来减少线程的构造/破坏。
我的问题是:对于这样的I/O线程,什么是一个好的截断点?我知道这只是一个粗略的估计,但我们说的是几百吗?成千上万的吗?
我怎么才能算出这个界限呢?
编辑:
感谢大家的回复,似乎我只是要测试一下,以找出我的线程数上限。问题是:我怎么知道我已经达到上限了呢?我到底应该测量什么?
当前回答
正如帕克斯所说,衡量,而不是猜测。这就是我为DNSwitness所做的事情,结果令人惊讶:理想的线程数比我想象的要高得多,大约15,000个线程才能获得最快的结果。
当然,这取决于很多东西,这就是为什么你必须衡量自己。
在Combien de fils d'exécution ?中的完整测量(仅法语)。
其他回答
我认为这有点回避你的问题,但是为什么不把它们分成进程呢?我对网络的理解(从以前模糊的日子里,我根本就没有编写网络代码)是每个传入的连接都可以作为一个单独的进程来处理,因为如果有人在您的进程中做了一些讨厌的事情,它不会破坏整个程序。
ryeguy,我目前正在开发一个类似的应用程序,我的线程数设置为15。不幸的是,如果我把它增加到20,它就崩溃了。所以,是的,我认为处理这个问题的最好方法是测量您当前的配置是否允许多于或少于X个线程。
我已经编写了大量多线程应用程序。我通常允许由配置文件指定潜在线程的数量。当我针对特定客户进行调优时,我将数值设置得足够高,以至于所有CPU核心的利用率都相当高,但还没有高到遇到内存问题(当时这些是32位操作系统)。
换句话说,一旦你达到某个瓶颈,比如CPU、数据库吞吐量、磁盘吞吐量等,添加更多的线程不会提高整体性能。但在达到这一点之前,请添加更多线程!
请注意,这是假设系统是专门为你的应用程序,你不需要很好地发挥(避免饥饿)其他应用程序。
在大多数情况下,您应该允许线程池处理这个问题。如果您发布一些代码或提供更多细节,可能更容易看到是否有某些原因导致线程池的默认行为不是最好的。
你可以在这里找到更多关于如何工作的信息:http://en.wikipedia.org/wiki/Thread_pool_pattern
“大铁”的答案通常是每个有限的资源一个线程——处理器(CPU限制),臂(I/O限制)等等——但这只有在您能够将工作路由到要访问的资源的正确线程时才有效。
在不可能的情况下,考虑您拥有可替代资源(cpu)和不可替代资源(武器)。对于CPU来说,将每个线程分配给特定的CPU并不重要(尽管这有助于缓存管理),但对于手臂,如果不能将线程分配给手臂,则需要考虑排队理论以及让手臂忙碌的最佳数量。一般来说,我认为如果您不能基于所使用的臂路由请求,那么每个臂有2-3个线程将是正确的。
当传递给线程的工作单元没有执行合理的原子工作单元时,就会出现复杂情况。例如,你可以让线程在一个点访问磁盘,在另一个点在网络上等待。这增加了“裂缝”的数量,其他线程可以进入并做有用的工作,但它也增加了其他线程污染彼此缓存的机会,等等,并使系统陷入困境。
当然,您必须将所有这些与线程的“重量”进行权衡。不幸的是,大多数系统都有非常重量级的线程(而他们所谓的“轻量级线程”通常根本就不是线程),所以最好在低级别上犯错。
我在实践中看到的是,非常细微的差异可能会对最佳线程的数量产生巨大的影响。特别是,缓存问题和锁冲突会极大地限制实际并发的数量。