python多线程+GIL

---恢复内容开始---

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:

上一篇:死锁现象与递归锁 信号量 GIL全局解释器锁 GIL与lock锁的区别 验证计算密集型IO密集型的效率 多线程实现socket通信 进程池, 线程池


下一篇:你是否真的了解全局解析锁(GIL)