日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

python学习-----9.7-----GIL、死锁递归锁、信号量,event事件

發(fā)布時(shí)間:2025/7/14 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python学习-----9.7-----GIL、死锁递归锁、信号量,event事件 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

GIL介紹

  GIL本質(zhì)就是一把互斥鎖,既然是互斥鎖,所有互斥鎖的本質(zhì)都一樣,都是將并發(fā)運(yùn)行變成串行,以此來(lái)控制同一時(shí)間內(nèi)共享數(shù)據(jù)只能被一個(gè)任務(wù)所修改,進(jìn)而保證數(shù)據(jù)安全。每個(gè)進(jìn)程內(nèi)都會(huì)存在一把GIL,同一個(gè)進(jìn)程內(nèi)的多個(gè)線程必須搶到GIL之后才能使用Cpython解釋器來(lái)執(zhí)行自己的代碼,即同一個(gè)進(jìn)程下的多個(gè)線程無(wú)法實(shí)現(xiàn)并行,但是可以實(shí)現(xiàn)并發(fā)

  在Cpython解釋器下,如果想實(shí)現(xiàn)并行可以開啟多個(gè)進(jìn)程

為何要有GIL

  因?yàn)镃python解釋器的垃圾回收機(jī)制不是線程安全的

總結(jié):

  io密集型:用多線程(開發(fā)中大部分用多線程)

  計(jì)算密集型:用多進(jìn)程

?

GIL與自定義互斥鎖的區(qū)別

  前者是解釋器級(jí)別的(當(dāng)然保護(hù)的就是解釋器級(jí)別的數(shù)據(jù),比如垃圾回收的數(shù)據(jù)),后者是保護(hù)用戶自己開發(fā)的應(yīng)用程序的數(shù)據(jù),很明顯GIL不負(fù)責(zé)這件事,只能用戶自定義加鎖處理,即Lock

  鎖通常被用來(lái)實(shí)現(xiàn)對(duì)共享資源的同步訪問。為每一個(gè)共享資源創(chuàng)建一個(gè)Lock對(duì)象,當(dāng)你需要訪問該資源時(shí),調(diào)用acquire方法來(lái)獲取鎖對(duì)象(如果其它線程已經(jīng)獲得了該鎖,則當(dāng)前線程需等待其被釋放),待資源訪問完后,再調(diào)用release方法釋放鎖:

from threading import Thread,Lock import os,time def work():global nlock.acquire()temp=ntime.sleep(0.1)n=temp-1lock.release() if __name__ == '__main__':lock=Lock()n=100l=[]for i in range(100):p=Thread(target=work)l.append(p)p.start()for p in l:p.join()print(n) #結(jié)果肯定為0,由原來(lái)的并發(fā)執(zhí)行變成串行,犧牲了執(zhí)行效率保證了數(shù)據(jù)安全 View Code

?

?

死鎖與遞歸鎖

  死鎖現(xiàn)象:指的是互相拿了對(duì)方需要的鑰匙但都不放手,導(dǎo)致了程序的阻塞

  遞歸鎖:就是為了解決死鎖現(xiàn)象:RLOOK

  

from threading import Thread,Lock import time mutexA=Lock() mutexB=Lock()class MyThread(Thread):def run(self):self.func1()self.func2()def func1(self):mutexA.acquire()print('\033[41m%s 拿到A鎖\033[0m' %self.name)mutexB.acquire()print('\033[42m%s 拿到B鎖\033[0m' %self.name)mutexB.release()mutexA.release()def func2(self):mutexB.acquire()print('\033[43m%s 拿到B鎖\033[0m' %self.name)time.sleep(2)mutexA.acquire()print('\033[44m%s 拿到A鎖\033[0m' %self.name)mutexA.release()mutexB.release()if __name__ == '__main__':for i in range(10):t=MyThread()t.start()''' Thread-1 拿到A鎖 Thread-1 拿到B鎖 Thread-1 拿到B鎖 Thread-2 拿到A鎖 然后就卡住,死鎖了 ''' View Code

?

?

信號(hào)量

  semaphore 控制統(tǒng)一進(jìn)程下的并發(fā)的線程個(gè)數(shù)

?

from threading import Thread,Semaphore import time,randomsm=Semaphore(5)def task(name):sm.acquire()print('%s正在上廁所'%name)time.sleep(random.randint(1,3))sm.release()if __name__ == '__main__':for i in range(20):t=Thread(target=task,args=('路人%s'%i,))t.start() View Code

?

Event

  

線程的一個(gè)關(guān)鍵特性是每個(gè)線程都是獨(dú)立運(yùn)行且狀態(tài)不可預(yù)測(cè)。如果程序中的其 他線程需要通過(guò)判斷某個(gè)線程的狀態(tài)來(lái)確定自己下一步的操作,這時(shí)線程同步問題就會(huì)變得非常棘手。為了解決這些問題,我們需要使用threading庫(kù)中的Event對(duì)象。 對(duì)象包含一個(gè)可由線程設(shè)置的信號(hào)標(biāo)志,它允許線程等待某些事件的發(fā)生。在 初始情況下,Event對(duì)象中的信號(hào)標(biāo)志被設(shè)置為假。如果有線程等待一個(gè)Event對(duì)象, 而這個(gè)Event對(duì)象的標(biāo)志為假,那么這個(gè)線程將會(huì)被一直阻塞直至該標(biāo)志為真。一個(gè)線程如果將一個(gè)Event對(duì)象的信號(hào)標(biāo)志設(shè)置為真,它將喚醒所有等待這個(gè)Event對(duì)象的線程。如果一個(gè)線程等待一個(gè)已經(jīng)被設(shè)置為真的Event對(duì)象,那么它將忽略這個(gè)事件, 繼續(xù)執(zhí)行 為何引用Event from threading import Thread,Event import timeevent=Event()def light():print('紅燈正亮著')time.sleep(3)event.set()#綠燈亮def car(name):print('車%s正在等綠燈'%name)event.wait()#等燈綠print('車%s通行'%name)if __name__ == '__main__':#紅綠燈t1=Thread(target=light)t1.start()#for i in range(10):t=Thread(target=car,args=(i,))t.start() View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/Liu-guang-hui/p/9607129.html

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的python学习-----9.7-----GIL、死锁递归锁、信号量,event事件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。