from threading import Thread, Lock import time def func(): global n n -= 1 n = 10 t_list = [] for i in range(10): t = Thread(target=func,) t_list.append(t) t.start() for t in t_list: t.join() print(n)
这段代码结果我们知道,因为GIL的原因,结果是0
再看如下代码:
from threading import Thread, Lock import time def func(): global n temp = n time.sleep(0.1) n = temp - 1 n = 10 t_list = [] for i in range(10): t = Thread(target=func,) t_list.append(t) t.start() for t in t_list: t.join() print(n)
打印结果却是9
为什么呢?
因为在0.1秒之内,所有线程肯定都进来了,但是需要睡0.1秒,这就是阻塞状态,他们会把手里的数据让给其他线程,所以每个线程的temp都是10,阻塞结束,10减1全变成9都写入内存,最终n的值就是9了,这样就导致数据的不安全了。
怎么改进?加锁就可以了
from threading import Thread, Lock import time def func(lock): lock.acquire() global n temp = n time.sleep(0.1) n = temp - 1 lock.release() lock =Lock() n = 10 t_list = [] for i in range(10): t = Thread(target=func, args=(lock,)) t_list.append(t) t.start() for t in t_list: t.join() print(n)
这样打印的结果就是0了。