并发编程(八):创建多少线程合适

1.为什么使用多线程

主要是考量了两个度量指标:

  1. 延迟:发出请求到响应的时间
  2. 吞吐量:单位时间内能够处理的请求数量

在单核时代,多线程主要就是用来平衡 CPU 和 I/O 设备的。如果程序只有 CPU 计算,而没有 I/O 操作的话,多线程不但不会提升性能,还会使性能变得更差,原因是增加了线程切换的成本

但是在多核时代,这种纯计算型的程序也可以利用多线程来提升性能。为什么呢?因为利用多核可以降低响应时间

2.创建多少线程合适

这里我们分为两个场景讨论:

  1. CPU密集型
  2. I/O密集型

2.1.CPU密集型

多线程本质上是提升了多核的利用率,因此我们对于CPU密集型的场景,理论上:
$$
线程的数量 = CPU核数
$$
不过在实际开发中:线程的数量 = CPU 核数 +1

https://www.cnblogs.com/bugutian/p/6138880.html

如何查看CPU的核数(核数其实就是物理核),每个核有两个逻辑处理单元(逻辑核):

# 查看物理CPU个数
[root@AAA ~]# cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
2

# 查看每个物理CPU中core的个数(即核数)
[root@AAA ~]# cat /proc/cpuinfo| grep "cpu cores"| uniq
cpu cores    : 6

# 查看逻辑CPU的个数
[root@AAA ~]# cat /proc/cpuinfo| grep "processor"| wc -l
24

2.2.IO密集型

IO密集型的场景我们需要考虑CPU计算耗时和IO操作耗时的比率,例如CPU 计算和 I/O 操作的耗时是 1:2,那多少个线程合适呢?是 3 个线程,因为3个线程能够保证CPU和IO的利用率拉满。如下图所示:

image-20210812152907603

I/O 密集型计算场景,最佳的线程数是与程序中 CPU 计算和 I/O 操作的耗时比相关的,我们可以总结出这样一个公式:

最佳线程数 =1 +(I/O 耗时 / CPU 耗时)

我们令 R=I/O 耗时 / CPU 耗时,综合上图,可以这样理解:当线程 A 执行 IO 操作时,另外 R 个线程正好执行完各自的 CPU 计算。这样 CPU 的利用率就达到了 100%。

不过上面这个公式是针对单核 CPU 的,至于多核 CPU,也很简单,只需要等比扩大就可以了,计算公式如下:

最佳线程数 =CPU 核数 * [ 1 +(I/O 耗时 / CPU 耗时)]

但是I/O 耗时 / CPU 耗时的值其实是比较难计算出来,需要通过具体的压测(APM)去重点关注CPU、IO设备的利用率和性能指标(响应时间、吞吐量)之间的关系

其实建议在开发中不必去拘泥于具体的线程数,线程池的配置可以先按照经验配置一个,随时关注线程池大小对程序的影响:可以为你的程序配置一个全局的线程池,需要异步执行的任务,扔到这个全局线程池处理,线程池大小按照经验设置,每隔一段时间打印一下线程池的利用率

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×