Python的多线程有什么特点?

面试头条的时候:Python的多线程有什么特点?当时直接答不会。。

结论:Python的多线程是假的,不能有效的利用多核。

先看几个例子,

1. python的多线程

#coding=utf-8
from multiprocessing import Pool
from threading import Thread

from multiprocessing import Process


def loop():
    while True:
        pass

if __name__ == '__main__':

    for i in range(3):
        t = Thread(target=loop)
        t.start()

    while True:
        pass

我的电脑是4核,所以我开了4个线程,看一下CPU资源占有率:

我们发现CPU利用率并没有占满,大致相当于单核水平。而如果我们变成进程呢?

2. python的多进程
#coding=utf-8
from multiprocessing import Pool
from threading import Thread

from multiprocessing import Process


def loop():
    while True:
        pass

if __name__ == '__main__':

    for i in range(3):
        t = Process(target=loop)
        t.start()

    while True:
        pass

结果直接飙到了100%,说明进程是可以利用多核的!

我们再用Java/C重写一下,开启多线程。

3. java的多线程

package com.darrenchan.thread;

public class TestThread {
    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    while (true) {

                    }
                }
            }).start();
        }
        while(true){

        }
    }
}

由此可见,Java中的多线程是可以利用多核的,这是真正的多线程!而Python中的多线程只能利用单核,这是假的多线程!

为什么会这样?

GIL锁,然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行。这个GIL全局锁实际上把所有线程的执行代码都给上了锁,所以,多线程在Python中只能交替执行,即使100个线程跑在100核CPU上,也只能用到1个核。

GIL是Python解释器设计的历史遗留问题,通常我们用的解释器是官方实现的CPython,要真正利用多核,除非重写一个不带GIL的解释器。

怎么解决呢?

如果一定要通过多线程利用多核,那只能通过C扩展来实现,例如Numpy底层就是C++实现的。不过这样就失去了Python简单易用的特点

另一方面,Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响。

参考链接:

1. https://www.liaoxuefeng.com/wiki/1016959663602400/1017629247922688

2. 为什么有人说 Python 的多线程是鸡肋呢? - DarrenChan陈驰的回答 - 知乎 

原文地址:https://www.cnblogs.com/lfri/p/13409666.html