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,在有新任务添加时则选加入队列,不直接创建线程
      当队列满时,在有新任务时就创建新线程
  • 相关阅读:
    web----DNS解析
    iToken----开发前准备
    web----计算机网络通讯
    SpringCloud----基础
    微服务----理解
    微服务----docker-compose.yml属性详解
    微服务----一次构建,到处运行
    Linux----安装gcc
    微服务----Registry
    Linux----常用命令
  • 原文地址:https://www.cnblogs.com/panxuejun/p/10198102.html
Copyright © 2011-2022 走看看