多少个线程太多?

我正在写一个服务器,当请求传入时,我将每个动作分支到一个线程中。 我这样做是因为几乎每个请求都会使数据库查询。 我正在使用一个线程库来减少线程的构建/销毁。

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


编辑:

谢谢大家的回复,看来我只是要测试它才能找出我的线程数上限。 问题是,我怎么知道我已经达到了天花板? 我究竟应该测量什么?


有些人会说,两个线程太多 - 我不太在这个阵营中:-)

这是我的建议:措施,不要猜测。 其中一个建议是使其可配置并将其初始设置为100,然后将您的软件发布到野外并监视发生的情况。

如果你的线程使用率达到3,那么100就太多了。 如果在一天中的大部分时间都保持在100,则将其提高到200,看看会发生什么。

你实际上可以让你的代码本身监控使用情况,并在下次启动时调整配置,但这可能是矫枉过正。


澄清和阐述:

我不主张使用你自己的线程池子系统。 但是,由于您正在询问关于线程的良好临界点,我假设您的线程池实现能够限制创建的最大线程数(这是一件好事)。

我编写了线程和数据库连接池代码,它们具有以下功能(我认为这对性能至关重要):

  • 最小数量的活动线程。
  • 最大线程数。
  • 关闭一段时间未使用的线程。
  • 第一个以线程池客户端为单位设置最低性能的基线(该线程数始终可用)。 第二个设置活动线程对资源使用的限制。 第三个将您返回到安静时期的基线,以最大限度地减少资源使用。

    您需要平衡具有未使用线程的资源使用情况(A)和没有足够线程来完成工作的资源使用情况(B)。

    (A)通常是内存使用(堆栈等),因为不工作的线程不会使用大部分CPU。 (B)通常会延迟处理请求,因为您需要等待线程变为可用。

    这就是你衡量的原因。 如您所述,绝大多数线程将等待来自数据库的响应,以便它们不会运行。 有两个因素会影响你应该允许的线程数。

    首先是可用的数据库连接数量。 这可能是一个硬性限制,除非你可以在DBMS中增加它 - 我假设你的DBMS在这种情况下可以采用无限数量的连接(尽管你最好也是在测量它)。

    那么,你应该有多少线程取决于你的历史使用。 你应该运行的最小数量是你运行过的最小数量+ A%,绝对最小值(例如,并且可以像A一样配置)5。

    最大线程数应该是您的历史最大值+ B%。

    您还应该监视行为变化。 如果由于某种原因,您的使用率达到可用时间的100%(因此会影响客户的表现),您应该提高允许的最大值,直到再次提高B%为止。


    针对“我究竟应该测量什么?” 题:

    您应该特别测量的是在负载下并发使用的最大线程数量(例如,等待从DB调用返回)。 例如,增加10%的安全系数(强调,因为其他海报似乎将我的例子作为固定建议)。

    另外,这应该在生产环境中进行调整。 预先得到估计值是可以的,但你永远不知道生产会抛出什么东西(这就是为什么所有这些东西都应该在运行时可配置的原因)。 这是为了解决一些情况,例如客户来电的意外翻倍。


    这个问题已经被彻底讨论过了,我没有机会阅读所有的答案。 但在考虑并行线程数量的上限时,可以考虑几件事情,这些线程可以在给定系统中和平共存。

  • 线程堆栈大小:在Linux中,默认线程堆栈大小为8MB(您可以使用ulimit -a来查找它)。
  • 指定操作系统版本支持的最大虚拟内存。 Linux Kernel 2.4支持2 GB的内存地址空间。 与内核2.6,我有点大(3GB)
  • [1]显示了每个给定的最大VM支持的最大线程数的计算。 2.4的结果是约255线程。 对于2.6这个数字有点大。
  • 你有什么kindda内核调度程序。 将Linux 2.4内核调度程序与2.6进行比较,后者为您提供了一个O(1)调度,而不依赖于系统中存在的任务数量,而第一个更多的是O(n)。 因此内核调度的SMP能力也对系统中可持续线程的最大数量起到很好的作用。
  • 现在您可以调整堆栈大小以包含更多线程,但是必须考虑线程管理(创建/销毁和调度)的开销。 您可以对给定进程和给定线程强制执行CPU亲和性,以将它们绑定到特定CPU,以避免CPU之间的线程迁移开销并避免冷现金问题。

    请注意,可以根据自己的意愿创建数千个线程,但是当Linux耗尽虚拟机时,它只是随机启动查杀进程(即线程)。 这是为了防止实用程序配置文件被刷新。 (效用函数告诉我们关于给定数量的资源的系统范围的实用程序。在这种情况下,CPU周期和内存中的资源不变,实用程序曲线会随着越来越多的任务变平)。

    我确信Windows内核调度程序也可以处理这些资源的使用情况

    [1] http://adywicaksono.wordpress.com/2007/07/10/i-can-not-create-more-than-255-threads-on-linux-what-is-the-solutions/


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

    '最好的情况'是你的后面的线程会在第一个线程完成的时候停顿,或者一些线程在低争用的资源上会有低开销块。 最糟糕的情况是你开始颠簸缓存/磁盘/网络,整体吞吐量会下降。

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

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

    链接地址: http://www.djcxy.com/p/64507.html

    上一篇: How many threads is too many?

    下一篇: height of an image when page enlarges with CSS