cpu密集型:cpu使用率较高(也就是一些复杂运算,逻辑处理),所以线程数一般只需要cpu核数的线程就可以了。这一类型的在开发中多出现的一些业务复杂计算和逻辑处理过程中。

IO密集型:cpu使用率较低,程序中会存在大量IO操作占据时间,导致线程空余出来,所以通常就需要cpu核心的两倍的线程,当线程进行I/O操作空暇时启用其他线程继承使用cpu,提高使用率通过上述可以总结出:

最佳线上数目 = ((线程等待时间 + 线程CPU时间 )/线程CPU时间) * CPU数目,线程等待时间所占比例越高,需要越多线程。

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

接下来我们进行一一分析:

1:高并发、任务执行时间短的业务,线程池线程数可以设置为CPU核数+1,减少线程上下文的切换

2:并发不高、任务执行时间长的业务这就需要区分开看了:

a)假如是业务时间长集中在IO操作上,也就是IO密集型的任务,因为IO操作并不占用CPU,所以不要让所有的CPU闲下来,可以适当加大线程池中的线程数目,让CPU处理更多的业务

b)假如是业务时间长集中在计算操作上,也就是计算密集型任务,这个就没办法了,和(1)一样吧,线程池中的线程数设置得少一些,减少线程上下文的切换

(其实从一二可以看出无论并发高不高,对于业务中是否是cpu密集还是I/O密集的判断都是需要的当前前提是你需要优化性能的前提下)

3:并发高、业务执行时间长,解决这种类型任务的关键不在于线程池而在于整体架构的设计,

a.看看这些业务里面某些数据是否能做缓存是第一步

b.增加服务器是第二步,至于线程池的设置,设置参考 2 。最后,业务执行时间长的问题,也可能需要分析一下,看看能不能使用中间件(任务时间过长的可以考虑拆分逻辑放入队列等操作)对任务进行拆分和解耦。

服务端优化中的并发处理需要使用多线程

线程任务分两种:

1 计算(CPU)密集型,举例:计算圆周率、视频高清解码等

特点:占用cpu资源,线程切换无开销

公式: 线程数 = CPU核数+1

2 IO密集型

举例:开发大部分都是WEB应用,涉及到大量的网络传输,不仅如此,与数据库,与缓存间的交互也涉及到IO,一旦发生IO,线程就会处于等待状态,当IO结束,数据准备好后,线程才会继续执行。因此对于IO密集型的应用,我们可以多设置一些线程池中线程的数量,这样就能让在等待IO的这段时间内,线程可以去做其它事,提高并发处理效率。

特点:cpu消耗较少,线程切换有开销

公式:线程数 = CPU核心数/(1-阻塞系数)

这个阻塞系数一般为0.8~0.9之间,也可以取0.8或者0.9。套用公式,对于双核CPU来说,它比较理想的线程数就是20,当然这都不是绝对的,需要根据实际情况以及实际业务来调整。

Python的多线程在多核CPU上,只对于IO密集型计算产生正面效果;而当有至少有一个CPU密集型线程存在,那么多线程效率会由于GIL而大幅下降。

IO是指阻塞,比如:服务器的accept,python 中的input,或者端口占用

GIL是全局排它锁,如果多线程任务是IO密集型,就会直接释放GIL,解除阻塞,提高了性能,如果多线程任务是CPU密集型,因为一个进程只有一个GIL,多个线程共享这一个GIL,所以一个线程释放了GIL,另一个就会唤醒,而释放GIL的线程就会等待下一次被唤醒,导致效率不会提高,不过可以使用多进程解决。

总之:IO密集型使用多线程,CPU密集型使用多进程