---恢复内容开始---
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: