您的位置:首页 > 其它

多线程在共享变量中出现的问题

2018-04-02 23:48 411 查看
假设两个线程t1和t2都要对全局变量g_num(默认是0)进行加1运算,t1和t2都各对g_num加10次,g_num的最终的结果应该为20。但是由于是多线程同时操作,有可能出现下面情况:1、在g_num=0时,t1取得g_num=0。此时系统把t1调度为”sleeping”状态,把t2转换为”running”状态,t2也获得g_num=0
2、然后t2对得到的值进行加1并赋给g_num,使得g_num=1
3、然后系统又把t2调度为”sleeping”,把t1转为”running”。线程t1又把它之前得到的0加1后赋值给g_num。
4、这样导致虽然t1和t2都对g_num加1,但结果仍然是g_num=1
看一段代码:
import threading

def work1():
global num
for i in range(1000000):
num += 1

print('work1--', num)

def work2():
global num
for i in range(1000000):
num += 1

print('work2--', num)

num = 0

def main():
"""开启两个线程,修改同一个全局变量"""
t1 = threading.Thread(target=work1)
t2 = threading.Thread(target=work2)

t1.start()
t2.start()

if __name__ == '__main__':
main()
看运行结果:



这个结果由于全局变量共享导致的。
现在给大家一个解决的方案:
 某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。

首先一个创建互斥锁:
lock = threading.Lock()  # 创建锁

 lock.acquire()  # 获取锁

lock.release()  # 释放锁

把这个互斥锁加在‘num += 1’。当一个线程调用锁的acquire()方法获得锁时,锁就进入“locked”状态。
看一下加了锁之后的答案:



可以看到最后的结果,加入互斥锁后,其结果与预期相符。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息