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锁,拥有执行权限。而线程互斥锁是保证同一时刻只有一个线程能对数据进行操作,是数据级别的锁。
仅为个人理解,欢迎大神指正。
来源:https://blog.csdn.net/qq_37100012/article/details/102778108