Python多线程(下)

2022-01-11 16:24:53 浏览数 (1)

前言

上节课我们分享了Python多线程的基础语法,以及GIL的相关概念,这节课我们重点讲解一个知识点,就是多线程的数据安全问题。

数据安全问题

我们首先来举一个例子,这里定义两个函数,一个是自加1,一个时自减1,按正常的逻辑来说,最后这个值应该是0,但是程序每次运行的结果都不一样,有正数,也有负数。

代码语言:javascript复制
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值的改变。

我们举一个现实中的案例,很多人抢一张火车票,如果是多线程,当一个人在抢票时,突然切换到另外一个人买票,他买到了,然后又返回到第一个人,他这边还是显示的还有一张票,但其实后台已经没票了。

这时我们就可以手动加锁来解决这样的问题。

代码语言:javascript复制
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就是释放锁,这样就能保证数据的安全。

今天的分享就到这了,我们下期再见~

0 人点赞