python中的GIL锁与线程互斥锁的区别

python中的GIL锁与线程互斥锁的区别

GIL锁:
GIL的全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做的决定。某个线程想要执行,必须先拿到GIL,我们可以把GIL看作是“通行证”,并且在一个python进程中,GIL只有一个。拿不到通行证的线程,就不允许进入CPU执行。GIL只在cpython中才有。

互斥锁
那么多线程编程时通过调用threading模块的Lock函数,来获取一把互斥锁。
互斥锁就是对共享数据进行锁定,保证同一时刻只有一个线程操作数据。

GIL锁的释放
在python3.x中,GIL不使用ticks计数,改为使用计时器(执行时间达到阈值后,当前线程释放GIL),这样对CPU密集型程序更加友好,但依然没有解决GIL导致的同一时间只能执行一个线程的问题,所以效率依然不尽如人意。

那么下来用代码来解释互斥锁与GIL锁的区别

假设有这样一个场景:

import threading

# 定义全局变量
g_num = 0
# 循环一次给全局变量加1
def sum_num1():
    for i in range(1000000):
        global g_num
        g_num += 1

    print("sum1:", g_num)

# 循环一次给全局变量加1
def sum_num2():
    for i in range(1000000):
        global g_num
        g_num += 1
    print("sum2:", g_num)
if __name__ == '__main__':
    # 创建两个线程
    A = threading.Thread(target=sum_num1)
    B = threading.Thread(target=sum_num2)

    # 启动线程
    A.start()
    # 启动线程
    B.start()

当A线程拿到GIL锁,有了执行权限后,对全局变量g_num进行数据操作,当GIL锁的计时器执行时间达到阈值,释放GIL锁让别的线程执行,B线程拿到GIL锁后同样对g_num进行数据操作,当A线程再次拿到GIL锁时就会出现和上一次操作的数据结果不一致,此时就出现了资源抢夺,数据操作不安全,因此我们要自己手动对线程加锁。就算A线程拿到了GIL锁有了执行权限,那么如果他拿不到我们加的锁,就没有权限对数据进行操作,这样就保证了数据的安全。

总结

GIL锁是解释器级别的锁,保证同一时刻进程中只有一个线程拿到GIL锁,拥有执行权限。而线程互斥锁是保证同一时刻只有一个线程能对数据进行操作,是数据级别的锁。

仅为个人理解,欢迎大神指正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值