GIL-全局解释锁

GIL全局解释锁

在python中,存在一个GIL全局解释锁,这个锁并不是python特有的,而是cpython所有的,cpython是python的c语言写的解释器,使用jpython就不会出现GIL的问题

如果使用的多进程,进程与线程不同,进程与进程的内存空间是相互独立的,双核的cpu可以同时处理两个进程,因此如如果运行的是两个进程程序

from multiprocessing import Process

def run1():
    while True:
        pass
def run2():
    while True:
        pass

if __name__ == '__main__':
    p1 = Process(target=run1)
    p2 = Process(target=run2)
    p1.start()
    p2.start()

代码明显是死循环,而且使用的最快的方式进行死循环,一旦启动,两个进程都进入死循环,那么使用的虚拟机上模拟双核系统的linux系统中打开htop命令可以看到双核cpu都进入100%的模式

如果使用的是多线程操作代码

import threading

def run1():
    while True:
        pass
def run2():
    while True:
        pass

if __name__ == '__main__':
    p1 = threading.Thread(target=run1)
    p2 = threading.Thread(target=run2)
    p1.start()
    p2.start()

使用的是多线程操作,同样的方式观察cpu占用,发现实际上两个cpu都只占用的是50%,讲道理这两个线程也可以放在两个cpu中进行执行,死循环的执行效率非常高,应该直接就100%.那么这里只有50%就说明cpu没有被完全占用.

同样是python中,多线程和多进程就存在这样的差异.这不是python本身的问题,而是cpython这个解释器本身具有的问题,cpython采用的是全局解释锁的方式进行执行多线程的操作

cpu的运算本身是一次只能执行一个程序,因为存在时间片轮转的方式进行执行,在时间极段的情况下进行执行轮转,看起来就像是同时执行了多个程序一样.那么多核的cpu则执行的是多个程序,而cpython最坑的地方就是在于对线程的处理,无论是多少个cpu在cpython面前都没有卵用,cpython会截断所有线程直接进入cpu,而是由cpython来分配,类似于cpython执行时间轮转一样,一次只允许一个线程进入cpu执行,就算有多个cpu也没有卵用,其他cpu就算是空闲状态,cpython也不会允许在第一个线程没有执行完成退出cpu的情况下放一个线程进其他cpu

这就导致双核的cpu实际上每次只有一个cpu在执行线程,另外一个是闲置,当时间片轮转到下一个时,原本执行的线程被弹出,cpython将放下另外一个线程去cpu执行,此时这个线程是进第一个cpu执行还是第二个cpu,这个是cpython本身不可控的,由于程序执行非常快,对大量的处理而言这个线程进入任意一个cpu的可能性就是核数分之1,因为有两个核,所以是50%,而程序是死循环,快速执行,会直接占满cpu,因此会在htop里面看到cpu占用率都是50%,那么如果是4核,就会看到占用率为25%.以此类推

python要解决这个问题是没有办法的,python本身是不能解决的,要想解决需要调用c语言写的程序包.老子不会写c…那就没办法,彻底GG,当然换个没有全局解释锁的解释器也可以,不过官方推荐的cpython,你懂的

猜你喜欢

转载自blog.csdn.net/weixin_43959953/article/details/84899036
今日推荐