之前有一篇文章分享了有关Python多线程的一次基础语法以及GIL的相关概念,今天我们重点讲解多线程的数据安全问题。
数据安全问题
我们首先来举一个例子,这里定义两个函数,一个是自加1,一个时自减1,按正常的逻辑来说,最后这个值应该是0,但是程序每次运行的结果都不一样,有正数,也有负数。
import threading num = 0 def add(): global num for i in range(10000000): num += 1 def sub(): global num for i in range(10000000): num -= 1 t1 = threading.Thread(target=add) t2 = threading.Thread(target=sub) t1.start() t2.start() t1.join() t2.join() print(num)
这就是多线程的数据安全的问题,我简单解释一下,因为线程会在两个函数中来回切换,好比在add函数中,刚准备加1时,程序被打断,跳到了sub函数中继续执行,这就会导致num值的改变。
我们举一个现实中的案例,很多人抢一张票,如果是多线程,当一个人在抢票时,突然切换到另外一个人买票,他买到了,然后又返回到第一个人,他这边还是显示的还有一张票,但其实后台已经没票了。
锁
这时我们就可以手动加锁来解决这样的问题。
import threading num = 0 lock = threading.Lock() def add(): lock.acquire() global num for i in range(10000000): num += 1 lock.release() def sub(): lock.acquire() global num for i in range(10000000): num -= 1 lock.release() t1 = threading.Thread(target=add) t2 = threading.Thread(target=sub) t1.start() t2.start() t1.join() t2.join() print(num)
acquire函数就是申请锁,release就是释放锁,这样就能保证数据的安全。
今天的分享就到这了,我们下期再见~
标签:Python,t2,t1,threading,num,数据安全,多线程 From: https://www.cnblogs.com/q-q56731526/p/17139747.html