日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

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

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

GIL介紹

  GIL本質就是一把互斥鎖,既然是互斥鎖,所有互斥鎖的本質都一樣,都是將并發運行變成串行,以此來控制同一時間內共享數據只能被一個任務所修改,進而保證數據安全。每個進程內都會存在一把GIL,同一個進程內的多個線程必須搶到GIL之后才能使用Cpython解釋器來執行自己的代碼,即同一個進程下的多個線程無法實現并行,但是可以實現并發

  在Cpython解釋器下,如果想實現并行可以開啟多個進程

為何要有GIL

  因為Cpython解釋器的垃圾回收機制不是線程安全的

總結:

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

  計算密集型:用多進程

?

GIL與自定義互斥鎖的區別

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

  鎖通常被用來實現對共享資源的同步訪問。為每一個共享資源創建一個Lock對象,當你需要訪問該資源時,調用acquire方法來獲取鎖對象(如果其它線程已經獲得了該鎖,則當前線程需等待其被釋放),待資源訪問完后,再調用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) #結果肯定為0,由原來的并發執行變成串行,犧牲了執行效率保證了數據安全 View Code

?

?

死鎖與遞歸鎖

  死鎖現象:指的是互相拿了對方需要的鑰匙但都不放手,導致了程序的阻塞

  遞歸鎖:就是為了解決死鎖現象: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

?

?

信號量

  semaphore 控制統一進程下的并發的線程個數

?

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

  

線程的一個關鍵特性是每個線程都是獨立運行且狀態不可預測。如果程序中的其 他線程需要通過判斷某個線程的狀態來確定自己下一步的操作,這時線程同步問題就會變得非常棘手。為了解決這些問題,我們需要使用threading庫中的Event對象。 對象包含一個可由線程設置的信號標志,它允許線程等待某些事件的發生。在 初始情況下,Event對象中的信號標志被設置為假。如果有線程等待一個Event對象, 而這個Event對象的標志為假,那么這個線程將會被一直阻塞直至該標志為真。一個線程如果將一個Event對象的信號標志設置為真,它將喚醒所有等待這個Event對象的線程。如果一個線程等待一個已經被設置為真的Event對象,那么它將忽略這個事件, 繼續執行 為何引用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

?

轉載于:https://www.cnblogs.com/Liu-guang-hui/p/9607129.html

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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。