python基础--GIL全局解释器锁、Event事件、信号量、死锁、递归锁
ps:python解釋器有很多種,最常見的就是C python解釋器
GIL全局解釋器鎖:
GIL本質(zhì)上是一把互斥鎖:將并發(fā)變成串行,犧牲效率保證了數(shù)據(jù)的安全
用來阻止同一個(gè)進(jìn)程下的多個(gè)線程的同時(shí)執(zhí)行(同一個(gè)進(jìn)程內(nèi)多個(gè)線程無法實(shí)現(xiàn)并行但是可以實(shí)現(xiàn)并發(fā))
GIL的存在是因?yàn)镃 python解釋器的內(nèi)存管理不是線程安全的
垃圾回收機(jī)制:
1、引用計(jì)數(shù)
2、標(biāo)記清除
3、分代回收
研究python 的多線程是否有用的話需要分情況討論:
同時(shí)執(zhí)行四個(gè)任務(wù)? 計(jì)算密集型:10s
# 計(jì)算密集型 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()) # 本機(jī)為6核start=time.time()for i in range(6):# p=Process(target=work) #耗時(shí) 4.732933044433594p=Thread(target=work) #耗時(shí) 22.83087730407715 l.append(p)p.start()for p in l:p.join()stop=time.time()print('run time is %s' %(stop-start))?
單核情況下:
開線程更節(jié)省資源
多核情況下:
開進(jìn)程:10s
開線程:40s
同時(shí)執(zhí)行四個(gè)IO密集型任務(wù)
# 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()) #本機(jī)為6核start=time.time()for i in range(4000):p=Process(target=work) #耗時(shí)9.001083612442017s多,大部分時(shí)間耗費(fèi)在創(chuàng)建進(jìn)程上# p=Thread(target=work) #耗時(shí)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# 先生成一個(gè)event對象 e = Event()def light():print('紅燈正亮著')time.sleep(3)e.set() # 發(fā)信號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()
?
?
?
信號量:在不同的領(lǐng)域中,對應(yīng)不同的知識點(diǎn)
互斥鎖:一個(gè)廁所(一個(gè)坑)
信號量:公共廁所(多個(gè)坑位)
?
死鎖:
RLock可以被第一個(gè)搶到鎖的人連續(xù)的acquire和release
每acquire一次鎖身上的計(jì)數(shù)就加1
每release一次鎖身上的計(jì)數(shù)就減1
只要是鎖的計(jì)數(shù)不為0 其他人都不能搶
class MyThread(Thread):def run(self): # 創(chuàng)建線程自動(dòng)觸發(fā)run方法 run方法內(nèi)調(diào)用func1 func2相當(dāng)于也是自動(dòng)觸發(fā) self.func1()self.func2()def func1(self):mutexA.acquire()print('%s搶到了A鎖'%self.name) # self.name等價(jià)于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))?
轉(zhuǎn)載于:https://www.cnblogs.com/tulintao/p/11354459.html
總結(jié)
以上是生活随笔為你收集整理的python基础--GIL全局解释器锁、Event事件、信号量、死锁、递归锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nginx技术研究系列7-Azure环境
- 下一篇: OpenCV计算机视觉实战(Python