python執行緒喚醒 Python中的執行緒

2021-10-13 08:33:25 字數 3452 閱讀 3764

執行緒同步

概念執行緒同步,執行緒間協同,通過某種技術,讓乙個執行緒訪問某些資料時,其他執行緒不能訪問這些資料,直到該執行緒完成對資料的操作.

臨界區(critical section) 互斥量(mutex) 訊號量(semaphore) 時間(event)

event事件

event事件,是執行緒間通訊機制中最簡單的實現,使用乙個內部標記的flag,通過flag的true或false的變化來進行操作.

名稱含義

set()

標記設定為true

clear()

標記設定為false

is_set()

標記是否為true

wait(timeout=none)

設定等標記為true的時長,none為無限等待.等到返回true,未等到超時返回false,不設定預設無限等

總結使用同乙個event物件的標記flag

誰wait就是等到flag變為true,或等到超時返回false,不限制等待個數

wait的使用

event的wait優於time.sleep,它會更快的切換到其他程序,提高併發效率.

lock(互斥鎖,互斥量)

鎖,凡是存在共享資源爭搶的地方都可以使用鎖,從而保證只有乙個使用者可以完全使用這個資源.

一旦執行緒獲得鎖,其他試圖獲取鎖的執行緒將被阻塞

名稱含義

acquire(blocking=true,timeout=-1)

預設阻塞,阻塞可以設定超時時間.非阻塞時,timeout禁止設定.成功獲取鎖,返回true,否則返回false

release()

釋放鎖,可以從任何執行緒呼叫釋放.已上鎖的鎖,會被重置為unlocked未上鎖的鎖上呼叫,拋runtimeerror異常

加鎖,解鎖

一般來說,有加鎖就需要解鎖,一旦加鎖後解鎖前,還要執行一些**,就可能拋異常,鎖無法釋放,但是當前執行緒就可能因為這個異常被終止,產生死鎖.一般為邏輯問題.

常用語句:

使用try,,,finally語句保證鎖的釋放

with上下文管理,鎖物件支援上下文管理

注意事項:

少用.使用了鎖,多執行緒訪問被鎖的資源時,就成了序列,要麼排隊執行,要麼爭搶執行

加鎖時間越短越好,不需要就立即釋放鎖

一定要避免死鎖

遞迴鎖rlock(可重入鎖)

遞迴鎖,是執行緒相關鎖,個人認為,鎖的是乙個執行緒

當鎖未釋放完,其他執行緒獲取鎖會被阻塞,知道當前持有鎖的執行緒釋放完鎖

condition

構造方法:condition(lock= none),可以摻入乙個lock或者rlock鎖物件,預設rlock

名稱含義

acquire(*args)

獲取鎖wait()

等待或超時

notify(n= 1)

喚醒之多指定數目個數的等待執行緒,沒有等待的執行緒就沒有任何操作

notify_all()

喚醒所有等待的執行緒

總結condition用於生成者消費者模型中,解決生產者消費者速度匹配的問題.

採用通知機制,效率極高

使用方法:

使用condition,必須先acquire,用完了要release,預設使用rlock.最好的方式是使用with上下文

消費者wait,等待通知

生產者生產好訊息,對消費者傳送通知,可以使用notify或者notify_all方法.

barrier柵欄(路閘)

wait超時

semaphore訊號量

和lock很想,訊號量物件內部維護乙個倒計數器,每一次acquire都會減1,當acquire方法發現技術為0就阻塞請求的執行緒,知道其他執行緒對訊號量release後,計數大於0,恢復阻塞的執行緒.

名稱含義

semaphore(value=1)

構造方法.value小於0,拋valueerror異常

acquire()

獲取訊號量,計數器減1,成功返回true

release()

釋放訊號量,計數器加1

計數器永遠不會低於0,因為acquire的時候,發現是0,都會被阻塞.

from threading import semaphore,lock

from threading import current_thread

from threading import thread

import time

sm = semaphore(5)#5個馬桶

def task():

sm.acquire()

print(f' work')

time.sleep(1)

sm.release()

for line in range(20):

t.thread(target=task)

t.start

訊號量和鎖

鎖,值允許同乙個時間乙個執行緒獨佔資源,它是特殊的訊號量,即訊號量計數器初值為1.

訊號量,可以多個執行緒訪問共享資源,但這個共享資源數量有限.

資料結構和gil

queue

標準庫queue模組,提供

fifo的佇列:先進先出

lifo的佇列:後進先出

優先佇列:根據引數內,數字的大小進行分級,數值越小,優先順序越高(字串會有自己的演算法,不建議使用)

queue是執行緒安全的,適用於多執行緒間安全的交換資料.內部使用了lock,condition

import queue

q = queue.queue()

q.put(1)

q.put(2)

q.put(3)

print(q.get()) #1

q = queue.lifoqueue()

q.put(1)

q.put(2)

q.put(3)

print(q.get()) # 3

gil全域性直譯器鎖(global interpreter lock)

cpython在直譯器程序級別有把鎖.叫gil全域性直譯器鎖.

gil保證cpython程序中,只有乙個執行緒執行位元組碼,甚至多核cpu情況下,也會當乙個程序a中的執行緒執行時,阻塞其他cpu上a程序的執行緒.相當於,cpython中永遠沒有真正微觀實際意義上的多執行緒.

cpython中,io密集型,使用多執行緒;cpu密集型,使用多繼承,繞開gil

ruby也有gil,如果高併發的話,用erlang或者go

​python中絕大多數內建資料結構讀寫都是原子操作.(即不會被優先順序更高的執行緒打斷,執行緒安全)

​由於gil存在,python的內建資料型別在多執行緒程式設計的時候就變程了安全的了,但是實際上他們本身不是執行緒安全型別.

原子操作:原子操作,就是不能被更高等級中斷搶奪優先的操作。由於作業系統大部分時間處於開中斷狀態,所以,乙個程式在執行的時候可能被優先順序更高的執行緒中斷。而有些操作是不能被中斷的,不然會出現無法還原的後果,這時候,這些操作就需要原子操作。就是不能被中斷的操作。

執行緒喚醒機制

object類中提供了三個方法 wait 等待 notify 喚醒單個執行緒 notifyall 喚醒所有執行緒 public class student public class setthread implements runnable override public void run catc...

C 自動喚醒執行緒

在通常的程式設計中,我們時常會不斷地啟動新執行緒來完成不斷出現的新任務.而由於任務的大小不確定性,以及出現要處理的任務的時間的不確定性,使得我們的好多程式總是在不斷地在開啟執行緒,並完成某任務後就退出執行緒.當每次任務不大,可又總是有任務頻繁出現時,總是不斷地開啟並退出執行緒.這開啟並退出執行緒所消...

執行緒等待與喚醒

標籤 多執行緒 所有的等待和喚醒執行緒,都是針對某個具體物件例項的.api介面 說明wait 讓當前執行緒進入等待 阻塞 狀態,直到其他執行緒呼叫此物件的notify 或notifyall 來喚醒,之後該執行緒進入就緒狀態.wait long timeout 讓當前執行緒進入阻塞狀態,直到其他執行緒...