Python学习,线程互斥锁递归锁死锁

本文探讨了Python中的GIL全局解释器锁,解释了为何在GIL存在下仍需使用线程锁。线程锁确保原子操作,防止数据不安全。介绍了互斥锁的概念,用于在同一时间只允许一个线程访问资源。接着讨论了死锁及其产生的条件,并提出递归锁作为解决死锁的一种方式。
摘要由CSDN通过智能技术生成

一、为什么有了GIL还要给线程加锁

先说一下GIL,所谓的GIL,也叫全局解释器锁,它限制了任何时候都只能有一个线程进入CPU进行计算,所以python所谓的多线程并不能真正的并行。

那为什么有了GIL还需要给线程加锁呢?不是直接一个线程处理完一个数据才轮到下一个线程进行吗?线程锁不是多此一举?

解决这个问题,我们得更深入到底层看看代码是怎么在CPU上运行的。在这里引入一个概念:原子操作

什么是原子操作

所谓的原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,不会运行到一半,然后CPU切换到另外的线程。原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序不可以被打乱。

像 C语言的i++和python中的+=,-=,*=,/=都不是原子操作,他们在被翻译成机器指令时实际上是分三个步骤的,比如 i-=1 这个操作本质是这样的:

1、先把内存中的1存储在CPU的寄存器中

2、CPU进行计算,减一

3、将寄存器的内容写到内存中。

在1-3这个过程中,线程完全有可能被切换,所以可能导致线程数据的不安全。所以加锁是必要的。我们看看下面的一个例子。

from threading import Lock,Thread
n = 10000000
def func():
    global n
    for i in range(1000000):
        n -= 1
t_lst = []
for i in range(10):
    t = Thread(target=func)
    t.start()
    t_lst.append(t)
for i in t_lst:i.join()
print(n)

上面代码过程就是用十个线程去将一个数减到0,但是运行结果如下:
在这里插入图片描述
所以这就验证
了线程数据的不安全性。下面是加锁的版本

from threading import Lock,Thread
n = 10000000
def func(lock):
    global n
    for i in range(1000000):
        lock.acquire()
        n = n 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值