java - 讨论一下Python线程池大小设置?
大家讲道理
大家讲道理 2017-04-18 10:18:10
0
1
646

在Java中,线程池大小通常被设置成CPU核心数+1,《Java Concurrency In Practise》8.2节中有这么一段话:

对于计算密集型的任务,在拥有N个处理器的系统上,当线程池的大小为N+1时,通常能实现最优的效率。(即使当计算密集型的线程偶尔由于缺失故障或者其他原因而暂停时,这个额外的线程也能确保CPU的时钟周期不会被浪费。)

btw: 不太熟悉Java,网上引用,没经过实践。

并发编程网上也有一篇相关的文章,要点如下:

  • 如果是CPU密集型应用,则线程池大小设置为N+1

  • 如果是IO密集型应用,则线程池大小设置为2N+1

最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目

线程等待时间所占比例越高,需要越多线程。线程CPU时间所占比例越高,需要越少线程。

疑问:对于n核和2n线程的处理器有什么需要注意的地方?


问题

以上都是引用自Java,Python方面的资料相对较少,所以想讨论一下。

由于CPython中GIL存在,Python同一时刻只能运行一个线程,所以这里不讨论计算型任务,只看IO型任务,Python线程池大小应该怎么设置才算合理?(IO最好的办法是采用异步,主要想讨论下不支持异步的情形)

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全部回复(1)
Peter_Zhu

如何估算srv需要设置的进程数?
原则
每个进程占用内存之和需要小于总内存

  • IO密集型
    涉及到一些阻塞式网络通讯开销,进程数可以开大一些,如配置成CPU 核数的3倍。如果业务中涉及的阻塞网络开销很多,可以再适当加大进程数,例如 CPU核数的5倍甚至更高。

  • CPU密集型
    也就是没有外部网络IO开销,或者没有阻塞的网络IO开销,例如使用 异步IO读取网络资源,进程不会被业务代码阻塞的情况下,可以把进程数设置成和 CPU核数一样。


中心思想就是,你响应的瓶颈是在 io 还是在 CPU。

  • 如果你的响应瓶颈是在 CPU

    现在程序是 python 线程模式,你只能用到 N 个 CPU 中的一个,理论上你开多少个线程和开单线程是没有区别的,而且你只能跑的多核 CPU 中一个 CPU 100% 的利用率。而实际上,如果你开了多于 2 个线程,还会存在 CPU 调度的问题(上下文的保存等消耗),可能会比单核心略慢。   
    
  • 如果你的响应瓶颈是在 IO(如:网络 IO)

    这就和其他语言一般的设置没有区别,主要是 比较 XN + 1(X 倍于 N 核心 CPU)先成为瓶颈还是 CPU 负载先成为瓶颈,因为如果成为了瓶颈之后,你再开多少线程对于程序的响应都是没有提高的(反而有可能下降)。
    
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!