假设两个线程都在访问 global count= 0, 每个进程都会执行 count +=1 。(1)(2)(3)第一个线程申请GIL然后,读取global count到及进程到 cpu ,(4)然后cpu执行到一半,(5)把这个线程停了,将上下文保存到自身寄存器中。注意这时候没返回结果。这时候解释器就会把GIL释放,
(6)(7)(8)第二个线程申请GIL执行如上步骤,读取count= 0 ,cpu计算结束后将结果count=1 返回,(10)(11)解释器拿到结果进行赋值,此时count=1,这个进程运行结束,(12)(13)然后cpu从寄存器中第一个线程的执行状态,继续执行,注意这个读取的是寄存器中的上下文,就是第一次执行时 count= 0,及第一个线程的上下文。计算结果返回count =1 返回。就造成了结果的错误。
import threading
count = 0
lock = threading.Lock() #申请一个锁
def count_():
global count #声明为全局变量
lock.acquire() #加锁,锁释放前不予许其他程序执行
count += 1
lock.release() #执行完 ,释放锁
thread_list = []
for i in range(10):
t = threading.Thread(target= count_)
t.start()
thread_list.append(t)
for t in thread_list:
t.join() #主程序等待所有程序执行完毕
print('Count:{: ^4}'.format(count))
import threading,time
def run1():
print("grab the first part data")
lock.acquire()
global num
num +=1
lock.release()
return num
def run2():
print("grab the second part data")
lock.acquire()
global num2
num2+=1
lock.release()
return num2
def run3():
lock.acquire()
res = run1()
print('--------between run1 and run2-----')
res2 = run2()
lock.release()
print(res,res2)
if __name__ == '__main__':
num,num2 = 0,0
lock = threading.RLock()
for i in range(10):
t = threading.Thread(target=run3)
t.start()
while threading.active_count() != 1:
print(threading.active_count())
else:
print('----all threads done---')
print(num,num2)