---恢复内容开始---
python的多线程实际上只有一个线程。
了让各个线程能够平均利用CPU时间,python会计算当前已执行的微代码数量,达到一定阈值后就强制释放GIL。而这时也会触发一次操作系统的线程调度(当然是否真正进行上下文切换由操作系统自主决定)。
GIL全局解释器锁: 保证同一时间只有一个线程得到数据并且只有一个线程执行,但是cpu调度时间到了以后,第一个线程无论是否完成均程等待状态(若未执行完毕,数据放入寄存器中)下一线程得到的依旧是原始的公共数据。
用户级lock:保证同一时间只有一个线程在修改数据。(可以避免几个线程同时对公共原始数据进行修改,提高线程效率)
为公共数据Lock:一个线程修改后,释放,下一进程才可再次进行修改。
RLock(递归锁):在一个大锁中还要再包含子锁
1 import threading, time 2 3 4 def run1(): 5 print("grab the first part data") 6 lock.acquire() 7 global num 8 num += 1 9 lock.release()10 return num11 12 13 def run2():14 print("grab the second part data")15 lock.acquire()16 global num217 num2 += 118 lock.release()19 return num220 21 22 def run3():23 lock.acquire()24 res = run1()25 print('--------between run1 and run2-----')26 res2 = run2()27 lock.release()28 print(res, res2)29 30 31 # if __name__ == '__main__':32 33 num, num2 = 0, 034 lock = threading.RLock()35 for i in range(10):36 t = threading.Thread(target=run3)37 t.start()38 39 while threading.active_count() != 1:40 print(threading.active_count())41 else:42 print('----all threads done---')43 print(num, num2)
线程锁(互斥锁Mutex)
信号量:和单个锁的区别是信号量有多个锁
1 import threading, time 2 3 # 信号量就是多个锁 4 def run(n): 5 semaphore.acquire()#信号量获取 6 time.sleep(1) 7 print("run the thread: %s\n" % n) 8 semaphore.release() # 信号量释放 9 10 11 if __name__ == '__main__':12 13 num = 014 semaphore = threading.BoundedSemaphore(5) # 最多允许5个线程同时运行15 for i in range(20):16 t = threading.Thread(target=run, args=(i,))17 t.start()18 19 while threading.active_count() != 1:20 pass # print threading.active_count()21 else:22 print('----all threads done---')23 print(num)
事件Event: