zoukankan      html  css  js  c++  java
  • 线程池大小设置,CPU的核心数、线程数的关系和区别,同步与堵塞完全是两码事

    线程池应该设置多少线程合适,怎么样估算出来。最近接触到一些相关资料,现作如下总结。

    最开始接触线程池的时候,没有想到就仅仅是设置一个线程池的大小居然还有这么多的学问,汗颜啊。

    首先,需要考虑到线程池所进行的工作的性质:

    • IO密集型
    • CPU密集型

    简单的分析来看,如果是CPU密集型的任务,我们应该设置数目较小的线程数,比如CPU数目加1。如果是IO密集型的任务,则应该设置可能多的线程数,由于IO操作不占用CPU,所以,不能让CPU闲下来。当然,如果线程数目太多,那么线程切换所带来的开销又会对系统的响应时间带来影响。

    《linux多线程服务器端编程》中有一个思路,CPU计算和IO的阻抗匹配原则。

    如果线程池中的线程在执行任务时,密集计算所占的时间比重为P(0<P<=1),而系统一共有C个CPU,为了让CPU跑满而又不过载,线程池的大小经验公式 T = C / P。在此,T只是一个参考,考虑到P的估计并不是很准确,T的最佳估值可以上下浮动50%。

    这个经验公式的原理很简单,T个线程,每个线程占用P的CPU时间,如果刚好占满C个CPU,那么必有 T * P = C。

    下面验证一下边界条件的正确性:

    假设C = 8,P = 1.0,线程池的任务完全是密集计算,那么T = 8。只要8个活动线程就能让8个CPU饱和,再多也没用了,因为CPU资源已经耗光了。

    假设C = 8,P = 0.5,线程池的任务有一半是计算,有一半在等IO上,那么T = 16.考虑操作系统能灵活,合理调度sleeping/writing/running线程,那么大概16个“50%繁忙的线程”能让8个CPU忙个不停。启动更多的线程并不能提高吞吐量,反而因为增加上下文切换的开销而降低性能。

    如果P < 0.2,这个公式就不适用了,T可以取一个固定值,比如 5*C。另外公式里的C不一定是CPU总数,可以是“分配给这项任务的CPU数目”,比如在8核机器上分出4个核来做一项任务,那么C=4

    文章如何合理设置线程池大小里面提到了一个公式:

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

    比如平均每个线程CPU运行时间为0.5s,而线程等待时间(非CPU运行时间,比如IO)为1.5s,CPU核心数为8,那么根据上面这个公式估算得到:((0.5+1.5)/0.5)*8=32。这个公式进一步转化为:

    最佳线程数目 = (线程等待时间与线程CPU时间之比 + 1)* CPU数目

    可以得出一个结论:
    线程等待时间所占比例越高,需要越多线程。线程CPU时间所占比例越高,需要越少线程。

    workQueue:保存任务的阻塞队列,与线程池的大小有关:

      当运行的线程数少于corePoolSize时,在有新任务时直接创建新线程来执行任务而无需再进队列
      当运行的线程数等于或多于corePoolSize,在有新任务添加时则选加入队列,不直接创建线程
      当队列满时,在有新任务时就创建新线程
  • 相关阅读:
    topcoder srm 320 div1
    topcoder srm 325 div1
    topcoder srm 330 div1
    topcoder srm 335 div1
    topcoder srm 340 div1
    topcoder srm 300 div1
    topcoder srm 305 div1
    topcoder srm 310 div1
    topcoder srm 315 div1
    如何统计iOS产品不同渠道的下载量?
  • 原文地址:https://www.cnblogs.com/panxuejun/p/10198102.html
Copyright © 2011-2022 走看看