from threading import Thread, Lockimport timedef func(): global n n -= 1n = 10t_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, Lockimport timedef func(): global n temp = n time.sleep(0.1) n = temp - 1n = 10t_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, Lockimport timedef func(lock): lock.acquire() global n temp = n time.sleep(0.1) n = temp - 1 lock.release()lock =Lock()n = 10t_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了。