在Python中多线程的创建、调用方式与Java基本一致。多线程可以共享全局变量,由此引出资源竞争而导致的问题。
#资源竞争导致的问题复现
import threading
num = 0
def work1():
global num
for i in range(1000000):#数要足够大才能显现出问题
num += 1
def work2():
global num
for i in range(1000000):
num += 1
if __name__ == "__main__":
w1 = threading.Thread(target = work1)
w2 = threading.Thread(target = work2)
w1.start()
w2.start()
w1.join()
w2.join()
print(num)
#测试输出结果:
1629026
问题原因分析:
for循环执行次数比较小时输出结果正确,而次数一但多起来问题就会显现。
线程在CPU上一般是并发执行,在第一个线程执行时间很短时的情况下,CPU还没有进行线程执行权切换时就线程已经执行完毕退出,此时程序输出结果正确,一但线程执行时间变长就有可能就会导致线程1正在执行时CPU把执行权交给线程2,这样就会导致计算结果出现差错。
解决方案:
使用互斥锁,每次只允许一个进程获取、修改全局变量。
#使用线程锁解决线程的资源竞争问题
import threading
num = 0
def work1(lock):
global num
for i in range(1000000):
lock.acquire()
num += 1
lock.release()
def work2(lock):
global num
for i in range(1000000):
lock.acquire()
num += 1
lock.release()
if __name__ == "__main__":
lock = threading.Lock()
w1 = threading.Thread(target = work1,args = (lock,))
w2 = threading.Thread(target = work2,args = (lock,))
w1.start()
w2.start()
w1.join()
w2.join()
print(num)