本文使用python语言讲解为什么多线程在不加锁的情况下同时修改一个变量是不安全的, 启动5个线程,每个线程都会对变量a执行100000次加1操作, 最后print(a)时,最直观的猜想,a的值是500000,然而实际情况却并不是这样,下面这段代码,将像你展示这种情形
import threading
import time
a = 0
def worker():
time.sleep(1)
global a
for i in range(100000):
a += 1
thread_lst = []
for i in range(5):
t = threading.Thread(target=worker)
thread_lst.append(t)
for t in thread_lst:
t.start()
for t in thread_lst:
t.join()
print(a)
启动5个线程,每个线程都会对变量a执行100000次加1操作, 最后print(a)时,最直观的猜想,a的值是500000,然而实际情况却并不是这样。
a最终的值会小于500000,这究竟是怎么一回事呢。
要想解释这个现象,就必须弄清楚,对变量加1这个操作是怎样完成的,在程序里,你只需要写a = a + 1 就可以完成一次对变量的加1操作,但在计算机内部,真实的加1过程却经历了很多
下图是一个线程对变量执行加1的过程
对变量执行加1操作,分为3个步骤
有了这个认识以后,再来看两个线程同时对变量a进行加1操作的过程
线程A在t1时刻启动,线程B在t2时刻启动,问题就出在t2这个时刻,仔细观察示意图,你会注意到几点事实
这就是事情的全部真相,t2时刻,线程B在线程A还没有完成一次加1操作时,将内存中的数据读取到寄存器中。
t3时刻,线程A将2写回到内存中,而这一刻,线程B在寄存器中进行加1操作,寄存器中的值是2
t4时刻,线程B将2写回到内存,两个线程都执行了加1操作,可内存中变量a的值仍然是2。
通过两个线程执行加1操作过程的分析,相信你已经明白了,问题的根本在于对于我们所写的一行代码,计算机在执行时有很多操作,而这些操作之间会互相影响,这导致了线程不安全,那么怎么才能消除这种影响呢,咱们下回分解。
QQ交流群: 211426309