概述
多线程并发修改同公共变量时,可能会出现bug
案例1
#coding=utf-8
import threading
num=0
def modify():
global num
#获取当前线程对象
t=threading.current_thread()
#注意:至少要循环10万次
for index in range(100000):
num+=1
if __name__ == "__main__":
#创建线程,此线程修改全局变量
t=threading.Thread(target=modify)
#创建线程,此线程打印全局变量
t2=threading.Thread(target=modify)
#启动线程
t.start()
t2.start()
#阻塞
t.join()
t2.join()
print('执行结束,num=%d'%(num))
两个线程分别循环100000次,结果应该是200000,那么执行结果不正确
说明:
在本程序中,一个线程中有两个线程,线程在执行时由系统调度,顺序不确定,顺序可能如下:
- 第一步,线程1获取num的值0
- 第二步,线程2获取num的值0
- 第三步,线程1计算后将1写入num
- 第四步,线程2计算后将1写入num
多线程并发访问公共变量时,可能每个线程得到的变量值是相同的,计算后赋值时,也是相同的
案例2
假设有车票500张,有3个售票窗口同时卖票,多线程编程模拟该例子,
注意: 本例sell()函数中有 循环
代码如下:
#coding=utf-8
from threading import Thread
import time
#票总数
count=500
#窗口数量
windownum=3
#初始化票号码
num=1
def sell(index):
global num
print('%d号售票口-开始售票,票号:%d'%(index,num))
#修改变量
while num<=count:
print('%d号售票口-售出票号:%d'%(index,num))
i=num+1
# time.sleep(0.00001)
num=i
print('%d号售票口-下一票号:%d'%(index,num))
else:
print('%d号售票口-售罄'%(index))
if __name__ == "__main__":
stime=time.time()
ts=[]
for index in range(windownum):
t=Thread(target=sell,args=(index,))
ts.append(t)
for item in ts:
item.start()
for item in ts:
item.join()
#主进程打印值
print('主进程,num=%s'%num)
etime=time.time()
print(etime-stime)
执行结果部分截图如下:
注意:多进程是由操作系统调度完成,所以每次运行结果不一样
原因
第一步,线程1获取num的值495
第二步,线程2获取num的值495
第三步,线程1计算后将496写入num
第四步,线程2计算后将496写入num
结论
多线程修改公共变量时,一个线程只执行一部分,还没执行完,另一个线程参与进来执行,导致公共变量错误



