gil是乙個互斥鎖(存在於cpython),保證資料的安全(以犧牲效率換區資料的安全性)
阻止同乙個程序內多個執行緒同時執行(不能並行但是能夠實現併發)
併發:發起來像是同時進行的
gil全域性直譯器存在的原因是cpython直譯器的記憶體管理不是執行緒安全的
同乙個程序下多個執行緒不能實現並行但能實現併發,多個程序下的執行緒可以實現並行。
在io密集的任務中
多執行緒優勢更為明顯(開啟的消耗資源少)
在計算密集的任務中
多程序有優勢(多cpu的優勢可以提現)
# 計算密集型
from multiprocessing import process
from threading import thread
import os,time
def work():
res=0
for i in range(100):
res*=i
if __name__ == '__main__':
l=print(os.cpu_count()) # 本機為8核
start=time.time()
for i in range(8):
# p=process(target=work) #耗時9.252728939056396
p=thread(target=work) #耗時35.369622230529785
p.start()
for p in l:
p.join()
stop=time.time()
print('run time is %s' %(stop-start))
# 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()) #本機為8核
start=time.time()
for i in range(600):
p=process(target=work) #耗時4.699530839920044
# p=thread(target=work) #耗時2.054128885269165
p.start()
for p in l:
p.join()
stop=time.time()
print('run time is %s' %(stop-start))
對於不同的資料,要想保證安全,需要加不同的鎖處理
gil並不能保證資料的安全,它是對cpython直譯器加鎖,針對的是執行緒,讓其無法並行,保證的是同一程序下多個執行緒間的安全
執行緒的互斥鎖保證的是資料的安全性
from threading import thread,lock
import time
mutex=lock()
n=100
def task():
global n
mutex.acquire() #如果不加自定義的鎖,那麼所有程序都得到了t=100的資料
t=n #確保t得到的是修改後的n
time.sleep(0.1)
n=t-1
mutex.release()
lis=
for i in range(100):
q=thread(target=task)
q.start()
for i in lis:
i.join()
print(n)
死鎖就是兩個執行緒或多個執行緒,得到了另一方需要獲取的鎖,而自身鎖無法釋放,導致執行緒的阻塞。
遞迴鎖就是,可以重複獲取的鎖(自定義鎖只能獲取(acquire)一次),每一次獲取都會計數+1,直到計數為0的時候,鎖才會釋放,其他執行緒才可以搶鎖。
#死鎖例子
from threading import thread,lock
import time
mutexa=lock()
mutexb=lock()
def task(name):
mutexa.acquire()#後來執行緒搶占了a鎖,但是b鎖未得到釋放,無法獲取
print('a get',name)
mutexb.acquire()
print('b get',name)
mutexa.release()
print('a lose',name)
mutexb.release()
print('b lose',name)
f1(name)
def f1(name):
mutexb.acquire()
print('b get',name)
time.sleep(0.1) #在io的時候,其他的執行緒已經搶占了a鎖,而b鎖並未釋放
mutexa.acquire()
print('a get',name)
mutexa.release()
print('a lose',name)
mutexb.release()
print('b lose',name)
if __name__ == '__main__':
for i in range(100):
p=thread(target=task,args=(i,))
p.start()
#遞迴鎖
from threading import thread,rlock
import time
mutex=rlock()#生成乙個遞迴鎖物件
class mythread(thread):
def run(self):
self.f1()
self.f2()
def f1(self):
mutex.acquire()
print(self.name,1)
mutex.acquire()
print(self.name,2)
mutex.release()
mutex.release()
def f2(self):
mutex.acquire()
print(self.name,3)
time.sleep(0.5)
mutex.acquire()
print(self.name,4)
mutex.release()
mutex.release()
if __name__ == '__main__':
for i in range(100):
p = mythread()
p.start()
#搶占廁所的例子
from threading import thread,semaphore
import time
sm=semaphore(5)#設定訊號量為5,只能有5個執行緒可以繼續執行
def task(name):
with sm:
print('%s 正在上廁所')
time.sleep(5)
if __name__=='__main__':
for i in range(20):
p=thread(target=task,args=(i,))
p.start()
from threading import event,thread
import time
event=event()
def light():
print('紅燈亮了')
time.sleep(5)
event.set() #解除阻塞
print('綠燈亮了')
def car(i):
print('%s 正在等紅燈'%i)
event.wait() #阻塞
print('%s 通行'%i)
if __name__=='__main__':
t=thread(target=light)
t.start()
for i in range(10):
c=thread(target=car,args=(i,))
c.start()
import queue
q=queue.queue(3)#queue按照佇列,先進先出
q.put(1)
q.put(2)
q.put(3)
print(q.get())
print(q.get())
print(q.get())
q = queue.lifoqueue(5)#堆疊,lifo,last in first out 先進後出
q.put(1)
q.put(2)
q.put(3)
q.put(4)
print(q.get())
q = queue.priorityqueue()#priorityqueue,優先順序,資料越小,優先順序越高
q.put((10,'a'))
q.put((-1,'b'))
q.put((100,'c'))
print(q.get())
print(q.get())
print(q.get())
# -1<10<100,所以順序是(-1, 'b'),(10, 'a'),(100, 'c')
GIL鎖,執行緒池,同步非同步
1.gil 是乙個全域性直譯器鎖 是一種互斥鎖 為什麼需要gil 因為乙個python.exe程序中只有一分直譯器,如果這個程序開啟了多個執行緒都要執行 多執行緒之間要競爭直譯器,一旦競爭就有可能出現問題 帶來的問題 同一時間只有乙個執行緒可以訪問直譯器 好處 保證了多執行緒的資料完全 thread...
多執行緒執行原理分析 GiL鎖 執行緒互斥鎖
首先丟擲問題 1.gil鎖和執行緒互斥鎖在整個程式中有何屌用?鎖的是什麼?2.多執行緒究竟是如果競爭offer?作業系統 直譯器 執行多執行緒的流程?直接貼圖 個人理解 參考繪製,如有問題,請指正 解釋 t1 1.執行緒1和執行緒2分別讀取共享資料池變數a的指標 2.t1競爭到gil鎖,cpytho...
GIL 全域性直譯器鎖
1 描述python中gil的概念,以及它對python多執行緒的影響?編寫乙個多執行緒抓取網頁的程式,並闡明多執行緒抓取程式是否可比單執行緒效能有提公升,並解釋原因。答 gil global interpreter lock,即全域性直譯器鎖 1 python語言和gil沒有半毛錢關係。僅僅是由於...