python基础--GIL全局解释器锁、Event事件、信号量、死锁、递归锁
ps:python解釋器有很多種,最常見的就是C python解釋器
GIL全局解釋器鎖:
GIL本質上是一把互斥鎖:將并發變成串行,犧牲效率保證了數據的安全
用來阻止同一個進程下的多個線程的同時執行(同一個進程內多個線程無法實現并行但是可以實現并發)
GIL的存在是因為C python解釋器的內存管理不是線程安全的
垃圾回收機制:
1、引用計數
2、標記清除
3、分代回收
研究python 的多線程是否有用的話需要分情況討論:
同時執行四個任務? 計算密集型:10s
# 計算密集型 from multiprocessing import Process from threading import Thread #mport os,time def work():res=0for i in range(100000000):res*=iif __name__ == '__main__':l=[]print(os.cpu_count()) # 本機為6核start=time.time()for i in range(6):# p=Process(target=work) #耗時 4.732933044433594p=Thread(target=work) #耗時 22.83087730407715 l.append(p)p.start()for p in l:p.join()stop=time.time()print('run time is %s' %(stop-start))?
單核情況下:
開線程更節省資源
多核情況下:
開進程:10s
開線程:40s
同時執行四個IO密集型任務
# IO密集型 from multiprocessing import Process from threading import Thread import threading import os,time def work():time.sleep(2)if __name__ == '__main__':l=[]print(os.cpu_count()) #本機為6核start=time.time()for i in range(4000):p=Process(target=work) #耗時9.001083612442017s多,大部分時間耗費在創建進程上# p=Thread(target=work) #耗時2.051966667175293s多 l.append(p)p.start()for p in l:p.join()stop=time.time()print('run time is %s' %(stop-start))?
單核:開線程更省資源
多核:開線程更省資源
Event事件:
from threading import Event,Thread import time# 先生成一個event對象 e = Event()def light():print('紅燈正亮著')time.sleep(3)e.set() # 發信號print('綠燈亮了')def car(name):print('%s正在等紅燈'%name)e.wait() # 等待信號print('%s加油門飆車了'%name)t = Thread(target=light) t.start()for i in range(10):t = Thread(target=car,args=('傘兵%s'%i,))t.start()
?
?
?
信號量:在不同的領域中,對應不同的知識點
互斥鎖:一個廁所(一個坑)
信號量:公共廁所(多個坑位)
?
死鎖:
RLock可以被第一個搶到鎖的人連續的acquire和release
每acquire一次鎖身上的計數就加1
每release一次鎖身上的計數就減1
只要是鎖的計數不為0 其他人都不能搶
class MyThread(Thread):def run(self): # 創建線程自動觸發run方法 run方法內調用func1 func2相當于也是自動觸發 self.func1()self.func2()def func1(self):mutexA.acquire()print('%s搶到了A鎖'%self.name) # self.name等價于current_thread().name mutexB.acquire()print('%s搶到了B鎖'%self.name)mutexB.release()print('%s釋放了B鎖'%self.name)mutexA.release()print('%s釋放了A鎖'%self.name)def func2(self):mutexB.acquire()print('%s搶到了B鎖'%self.name)time.sleep(1)mutexA.acquire()print('%s搶到了A鎖' % self.name)mutexA.release()print('%s釋放了A鎖' % self.name)mutexB.release()print('%s釋放了B鎖' % self.name)for i in range(10):t = MyThread()t.start()?
?
遞歸鎖:
import threadingclass MyThread(threading.Thread):def run(self):global n1, n2lock.acquire() # 加鎖n1 += 1print(self.name + ' set n1 to ' + str(n1))lock.acquire() # 再次加鎖n2 += n1print(self.name + ' set n2 to ' + str(n2))lock.release()lock.release()n1, n2 = 0, 0 lock = threading.RLock()if __name__ == '__main__':thread_list = []for i in range(5):t = MyThread()t.start()thread_list.append(t)for t in thread_list:t.join()print('final num:%d ,%d' % (n1, n2))?
轉載于:https://www.cnblogs.com/tulintao/p/11354459.html
總結
以上是生活随笔為你收集整理的python基础--GIL全局解释器锁、Event事件、信号量、死锁、递归锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nginx技术研究系列7-Azure环境
- 下一篇: 子页面赋值给父页面:window.ope