Python-GIL深度理解

1.GIL介绍

        GIL,意为全局解释器锁,是cPython执行多线程/进程计算密集型代码效果不如人意的主要原因。
        cPython限制一个进程内同时只能执行一个线程。
首先介绍一下,正常多线程/进程执行时,多线程/进程数据混乱的原因:
      cpu分成多个时间片段,启动10线程,分配10个cpu时间片段,当我累加数字设置比较小的时候,在单个cpu时间片段内,for循环代码就执行完,就不会产生数据混乱的。当我数据设置的比较大时,在单个cpu时间片段内,for循环代码就执行不完,并且没有分配2个或2个以上的连续的cpu时间片段,导致一个cpu时间片段没有执行完该线程,下一个线程开始执行了 ​ 原文链接:https://blog.csdn.net/YZL40514131/article/details/126198377

        GIL是CPython才有的限制。

 

    每个进程分配一个cPython解释器,垃圾回收功能也算解释器的一个线程,而且是线程不安全的。
    所以cPython限制一个进程内同时只能执行一个线程,这就是GIL。
    所以可以看出,GIL本质是个线程互斥锁。 GIL会在抢到锁后执行IO操作时被释放,所以IO密集型多线程/进程不受GIL影响,因为GIL会被不断释放。 
    Python的GIL(全局解释器锁)会在执行阻塞IO操作时被释放。这是因为在等待IO操作完成的过程中,Python线程不需要持有GIL,也不需要执行Python字节码。所以,在这种情况下,其他Python线程可以获得GIL并执行代码。

2.测试代码

#多线程执行以下代码,结果正常,因为GIL充当互斥锁。
def task():
    global g_n
    tem=g_n
    # time.sleep(0.05)
    g_n=tem-1
#以上代码等价于
def task():
    global g_n
    mutex.acquire()
    tem=g_n
    # time.sleep(0.05)
    g_n=tem-1
    mutex.release()
#但是time.sleep()执行后,出现数据混乱的问题,因为sleep是io操作,io操作提前释放了该线程的GIL,以至于没有互斥作用
def task():
    global g_n
    tem=g_n
    time.sleep(0.05)
    g_n=tem-1
#所以需要自己手动加上互斥锁
def task():
    global g_n
    mutex.acquire()
    tem=g_n
    time.sleep(0.05)
    g_n=tem-1
    mutex.release()#结果正确

完整测试代码:

import os
import random
import threading
import multiprocessing
import time
from multiprocessing import Process
from threading import Thread
g_n=180#初始值
cnt=int(10)
cpu_cnt=os.cpu_count()
mutex=threading.Lock()
def task():
    global g_n
    mutex.acquire()
    tem=g_n#取出全局变量的值
    # time.sleep(0.05)
    g_n=tem-1#每次减一
    mutex.release()
if __name__ == '__main__':
    l_p=[]
    print("cpu_cnt: ",cpu_cnt)
    for _ in range(cpu_cnt):#创建cpu核数个线程
        t=Thread(target=task)
        t.start()#执行
        l_p.append(t)
    for t in l_p:
        t.join()#同时结束
    print(f"实际为",g_n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值