---恢复内容开始---
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 num 11 12 13 def run2(): 14 print("grab the second part data") 15 lock.acquire() 16 global num2 17 num2 += 1 18 lock.release() 19 return num2 20 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, 0 34 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 = 0 14 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: