浅谈GIL

GIL全局解释锁

GIL演示

在python中,实际上多线程都是假的,因为有个GIL(全局解释锁),无论你有多少个线程,在最终执行的时候都只有一个CPU被调用

如果要真正意义上实现多线程的话可以使用C语言作为扩展

#单核CPU

在解释GIL问题,我先演示一下单核CPU和多核CPU

这里是我单核CPU的处理情况

浅谈GIL_第1张图片

然后我运行一个死循环

while True:
	pass

浅谈GIL_第2张图片

CPU一下子就满了

#多核CPU

接下来试试两核的CPU

这里我创建一个子线程也是死循环,主线程也是死循环,那么就有两个死循环了

代码如下:

import threading

def test():
    while True:
        pass

t1=threading.Thread(target=test)
t1.start()

while True:
    pass

执行前我的资源如下:

浅谈GIL_第3张图片

执行后:

浅谈GIL_第4张图片

哦吼,两个CPU却不是100%,而是两个各占50%

我们从理论上来说,我们两个线程应该各占一个CPU

如图:

浅谈GIL_第5张图片

但实际上调用的时候,Python有一个GIL,也就是全局解释锁

浅谈GIL_第6张图片

GIL会控制两个线程,线程1来就给一个CPU去执行,线程1执行完再给线程2给一个CPU执行,实际上是单线程的方式执行的

那么一定要解决这个问题怎么办呢,这个可以用C语言去扩展来解决这个问题

#C语言扩展实现多线程

C语言的代码如下

void DeadLoop()
{
        while(1)
        {
                ;
        }
}

然后在当前目录输入如下命令

gcc loop.c -shared -o libdeadloop.so

然后编写Python代码

from threading import Thread
from ctypes import *


lib = cdll.LoadLibrary("./libdeadloop.so")

t = Thread(target=lib.DeadLoop)

t.start()

#lib.DeadLoop()

while True:
    pass

然后运行python代码

浅谈GIL_第7张图片

一下子就满了

GIL是导致python变慢的原因吗

GIL锁是当初设计python的时候为了数据安全所做的决定,程序执行的时候都要经过GIL,而GIL分配一个程序给一个CPU,所以每个CPU都只能执行一个线程,所以GIL的原因导致python无法使用多CPU的特性,但是GIL是会释放的

在python2.x的中,GIL会按字节码的执行的数量来释放。

在python3.x中会按照时间片来释放,即隔一段时间就释放一次,遇到IO也会释放、或者遇到其他的一些需要时间很多的部分也会释放

在IO型操作而言

IO操作是整个系统中最占时间的部分,比一个单单的线程要高出上千上万倍,如果遇到IO还阻塞的话那真的是会让程序变得很慢了。即便是有很多线程,每个线程切换的时间都要远远低于IO操作,这部分切换的时间在运行程序中是微不足道的

所以,这样在IO型操作就相比于java等语言也不会慢到哪里去

在计算型操作而言

计算型任务基本上是完全占CPU,这个时候要么就用C语言重写关键部分,要么就直接调用多进程,一个进程就一个GIL,这样也可以完美的解决这个问题

计算型操作这里我拿个案例来说明

from threading import Thread

total=0
def add():
    global total
    for i in range(1000000):
        total+=1

def desc():
    global total
    for i in range(1000000):
        total-=1

if __name__ == "__main__":
    addtest=Thread(target=add)
    desctest=Thread(target=desc)

    addtest.start()
    desctest.start()

    addtest.join()
    desctest.join()

    print(total)
    
    
    #611367
    #-433619

执行结果都不一样

如果python没有时间片释放机制,那么肯定是执行完add再去执行desc,结果肯定是0。就是因为有时间片释放机制,所以每次的时间都不一样

你可能感兴趣的:(Python)