一、前提:

    python的多线程的问题:GIL导致PYTHON 无法使用到计算机的多核,仅能使用单核

    JAVA传统的多线程主要解决的问题:

        1、运行于多核CPU上,各线程可分布于CPU的各个核心,让程序真正的并发

        2、因为外设(IO外设)的速度不匹配,导致线程阻塞。所以需要多线程切换来让阻塞的线程让出CPU,让其它线程运行。

 

二、IO密集型的应用

1、未占满CPU单核的处理能力   

    1、1 python 多钱程的表现:  python没有GIL导致的缺点(或缺点不会特别明显)  

    1、2 性能:与普通的多线程性能差不多   

    1、3 建议:因为CPU占用率低于单核,而线程切换,又会占用CPU的资源,所以,在线程切换的次数很多,导致线程切换的性能损耗占比很高(线程切换的次数相关的因素:线程数量很多,IO阻塞时间很短 ),这个时候协程的优点表现明显,建议使用协程 ,否则,随便选

2、超过了 CPU单核的处理能力     

    2、1 python 多钱程的表现:  python表现出GIL导致的缺点,无法利用到计算机的多核   

    2、2 性能:性能远低于普通的多线程     

    2、3 建议:因为CPU占用率高于单核,为了利用到CPU其它核心,所以建议使用多进程的方式,利用CPU多核,提高程序的并发

3、进程+协程的模型(不能简单的使用多进程代替JAVA传统的多线程):

        传统的java多线程处理IO密集的方式,就是使用很多数量的线程,使用线程的切换来解决因为线程阻塞而浪费的CPU时间。IO的阻塞,会导致线程的切换。但是,IO的阻塞,不一定能导致进程的切换。而且,使用进程的切换比线程的切换的性能损耗大一个数量级。

应该使用多进程+协程的模型。使用协程来解决IO阻塞导致的切换,以便尽量减少进程的数量(建议:CPU核心 *2>进程的数量 >CPU核心),来减少进程的切换(进程的切换由操作系统调度,协程解决IO阻塞没有切换带来的性能损耗)。

 

三、CPU密集型的应用

python的协程和多线程都无法利用到CPU的多核,所以,必须多进程(但是进程数量不能太多)

 

四、现实:IO密集+CPU密集

一般的应用,很难完全的定位于IO密集型或是CPU密集型

举例:传统的WEB应用,WEB服务器看似IO密集 >>>CPU密集 ,但这种情况并非100%,尤其,在微服务的开发模式下(因为微服务数据私有),所以数据的计算处理都移到了WEB服务器上了(比如,数据的整合,排序,筛选)等等。

现实是很多时候,我们的应用都兼顾 IO密集和CPU密集,所以,在编程时,综合以上因素权衡选择合理的模型。

 

五、最后的一句话总结:

        未占满CPU单核的处理能力,多线程简单,协程简单高效

        超过了 CPU单核的处理能力 ,必须多进程,但切记,解决IO密集的方式仍然要使用多线程或协程。