python之GIL全域性直譯器鎖,自定義互斥鎖,死鎖與遞迴鎖
一.關於GIL與自定義互斥鎖的區別
1.GIL是python直譯器自帶的鎖,自定義互斥鎖是我們程式裡面自定義的鎖
2.GIL鎖只保證關於垃圾回收那一部分的資料是安全的,但是程式裡面自定義的資料GIL無法保證,只能增加自定義鎖
程式碼如下:
1.有自定義互斥鎖的情況
from threading import Thread,Lock
import time,random
n=100
mutex=Lock()
def task():
global n
with mutex:
temp=n
time.sleep(0.1)
n=temp-1
if __name__ == '__main__':
l=[]
for i in range(100):
t=Thread(target=task)
l.append(t)
t.start()
for t in l:
t.join()
print(n) #0
2.只有GIL鎖,沒有自定義互斥鎖的情況
from threading import Thread,Lock
import time,random
n=100
# mutex=Lock()
def task():
global n
# with mutex:
temp=n
time.sleep(0.1)
n=temp-1
if __name__ == '__main__':
l=[]
for i in range(100):
t=Thread(target=task)
l.append(t)
t.start()
for t in l:
t.join()
print(n) #99
二.死鎖與遞迴鎖
當自定義鎖運用的不得當,會造成死鎖,死鎖的解決方案是遞迴鎖 自定義鎖只能aquire一次 而遞迴鎖可以aquire多次
from threading import Thread,Lock,RLock
import time
mutexA=Lock()
mutexB=Lock()
#mutexB=mutexA=RLock()
class Mythead(Thread):
def run(self):
self.f1()
self.f2()
def f1(self):
mutexA.acquire()
print('%s 搶到A鎖' %self.name)
mutexB.acquire()
print('%s 搶到B鎖' %self.name)
mutexB.release()
mutexA.release()
def f2(self):
mutexB.acquire()
print('%s 搶到了B鎖' %self.name)
time.sleep(2)
mutexA.acquire()
print('%s 搶到了A鎖' %self.name)
mutexA.release()
mutexB.release()
if __name__ == '__main__':
for i in range(100):
t=Mythead()
t.start()
列印結果:
遞迴鎖可以被一個執行緒aquire多次,每aquire一次計數加一,導致其它執行緒無法aquire這把鎖(只有計數為零才可以被aquire)
from threading import Thread,Lock,RLock
import time
# mutexA=Lock()
# mutexB=Lock()
mutexB=mutexA=RLock()
class Mythead(Thread):
def run(self):
self.f1()
self.f2()
def f1(self):
mutexA.acquire()
print('%s 搶到A鎖' %self.name) ..1 ..2
mutexB.acquire()
print('%s 搶到B鎖' %self.name) ..1
mutexB.release()
mutexA.release()
def f2(self):
mutexB.acquire() ..1
print('%s 搶到了B鎖' %self.name) ..1
time.sleep(2)
mutexA.acquire()
print('%s 搶到了A鎖' %self.name)
mutexA.release()
mutexB.release()
if __name__ == '__main__':
for i in range(100):
t=Mythead()
t.start()
列印結果:
三.訊號量
訊號量本質也是一把鎖,但是與互斥鎖不一樣的是,訊號量是有多把鎖,能保證同一時刻多個執行緒同時執行
四.event事件
多個執行緒之間需要協同工作,一個執行緒的執行依賴另一個執行緒為它做好準備工作
from threading import Thread,Event
import time,random
event=Event()
def light():
print("紅燈正亮")
time.sleep(random.randint(1,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=("車輛%s" %i ,))
t.start()
五.執行緒Queue
import queue
q=queue.Queue() #先進先出
q.put(1)
q.put(2)
q.put(3)
print(q.get()) #1
print(q.get()) #2
print(q.get()) #3
q=queue.LifoQueue() #後進先出
q.put(10)
q.put(20)
q.put(30)
print(q.get()) #30
print(q.get()) #20
print(q.get()) #10
q=queue.PriorityQueue() #元組裡面第一個引數越小 優先順序越高
q.put((100,"a"))
q.put((0,"b"))
q.put((-1,"c"))
print(q.get()) #c
print(q.get()) #b
print(q.get()) #a
相關文章
- Python GIL(全域性直譯器鎖)Python
- Python提高:關於GIL(全域性直譯器鎖)與執行緒互斥鎖的理解Python執行緒
- 什麼是Python全域性直譯器鎖(GIL)?全域性直譯器鎖的好處!Python
- Python與全域性直譯器鎖Python
- Python培訓教程:什麼是Python全域性直譯器鎖(GIL)?Python
- Gil全域性解釋鎖和執行緒互斥鎖的關係執行緒
- python 協程 自定義互斥鎖Python
- Python 新提案:“廢除”全域性直譯器鎖 GIL | CPython 直譯器或許會變得更快Python
- 全域性鎖、表鎖、行鎖
- 全域性鎖和表鎖
- MySQL全域性鎖、表鎖以及行鎖MySql
- MySQL鎖(讀鎖、共享鎖、寫鎖、S鎖、排它鎖、獨佔鎖、X鎖、表鎖、意向鎖、自增鎖、MDL鎖、RL鎖、GL鎖、NKL鎖、插入意向鎖、間隙鎖、頁鎖、悲觀鎖、樂觀鎖、隱式鎖、顯示鎖、全域性鎖、死鎖)MySql
- MySQL學習之全域性鎖和表鎖MySql
- MySQL 全域性鎖和表鎖MySql
- 你是否真的瞭解全域性解析鎖(GIL)
- 讀寫鎖 ReentrantReadWriteLock 與 互斥鎖 的效率
- Python多執行緒與GIL鎖Python執行緒
- Python | 淺談併發鎖與死鎖問題Python
- MySQL鎖問題分析-全域性讀鎖MySql
- Python中的互斥鎖Python
- 鎖的使用與死鎖的避免
- 例項詳解 Java 死鎖與破解死鎖Java
- Java 中15種鎖的介紹:公平鎖,可重入鎖,獨享鎖,互斥鎖,樂觀鎖,分段鎖,自旋鎖等等Java
- Lock鎖之重入鎖與讀寫鎖
- MySQL鎖等待與死鎖問題分析MySql
- 【go】golang中鎖的用法-互斥鎖Golang
- 死鎖和可重入鎖
- MySQL 死鎖和鎖等待MySql
- Java 種15種鎖的介紹:公平鎖,可重入鎖,獨享鎖,互斥鎖等等...Java
- Java 種15種鎖的介紹:公平鎖,可重入鎖,獨享鎖,互斥鎖等等Java
- 死鎖
- 防手機鎖屏解鎖自定義ViewView
- 執行緒同步與互斥:互斥鎖執行緒
- MySQL/InnoDB中,樂觀鎖、悲觀鎖、共享鎖、排它鎖、行鎖、表鎖、死鎖概念的理解MySql
- liteos互斥鎖(七)
- [譯] part25: golang Mutex互斥鎖GolangMutex
- SQL SERVER死鎖查詢,死鎖分析,解鎖,查詢佔用SQLServer
- Linux之執行緒互斥鎖Linux執行緒