多執行緒和執行緒的同步

2021-08-14 02:55:21 字數 2631 閱讀 4494

一、執行緒同步的目的?

有一些特定的**或者資料不希望被多個執行緒執行,比如:乙個全域性變數被多個執行緒同時做自增操作時,可能會造成逾期結果和實現結果不一致的問題。

二、執行緒同步的幾種方法

執行緒同步有很多種方法,以下介紹三種方法:鎖同步、訊號量、events事件。

三、鎖同步

1、基本原理

鎖是python的threading模組提供的最基本的同步機制。在任一時刻,乙個鎖物件可能被乙個執行緒獲取,或者不被任何執行緒獲取。如果乙個執行緒嘗試去獲取乙個已經被另乙個執行緒獲取到的鎖物件,那麼這個想要獲取鎖物件的執行緒只能暫時終止執行直到鎖物件被另乙個執行緒釋放掉。

鎖通常被用來實現對共享資源的同步訪問。為每乙個共享資源建立乙個lock物件,當你需要訪問該資源時,呼叫acquire方法來獲取鎖物件(如果其它執行緒已經獲得了該鎖,則當前執行緒需等待其被釋放),待資源訪問完後,再呼叫release方法釋放鎖:

lock = lock()

lock.acquire() #: will block if lock is already held

#對共享資源進行操作

lock.release()

四、訊號量(semaphore)

1、基本原理

訊號量是乙個更高階的鎖機制。訊號量內部有乙個計數器而不像鎖物件內部有鎖標識,而且只有當占用訊號量的執行緒數超過訊號量時執行緒才阻塞。這允許了多個執行緒可以同時訪問相同的**區。

semaphore = threading.boundedsemaphore()

semaphore.acquire() #: counter減小

#對共享資源進行操作

semaphore.release() #: counter增大

當訊號量被獲取的時候,計數器減小;當訊號量被釋放的時候,計數器增大。當獲取訊號量的時候,如果計數器值為0,則該程序將阻塞。當某一訊號量被釋放,counter值增加為1時,被阻塞的執行緒(如果有的話)中會有乙個得以繼續執行。

五、events事件

1、基本原理

乙個事件是乙個簡單的同步物件,事件表示為乙個內部標識(internal flag),執行緒等待這個標識被其它執行緒設定,或者自己設定、清除這個標識。

event = threading.event()

#: 乙個客戶端執行緒等待flag被設定

event.wait()

#: 服務端執行緒設定或者清除flag

event.set()

event.clear()

一旦標識被設定,wait方法就不做任何處理(不會阻塞);當標識被清除時,wait方法將被阻塞直至其被重新設定。任意數量的執行緒可能會等待同乙個事件。

2、**舉例

我們以紅綠燈為例,燈(light)和車(car)為兩根執行緒,我們可以根據綠燈是否被設定作為事件,對上述兩個執行緒進行同步。

(1)light執行緒和car執行緒的同步關係

事件:綠燈是否被設定;綠燈如果被設定(set),car事件來到的時候不會阻塞,car可以執行;綠燈如果被清除(clear),car事件來到的時候(代表紅燈)會阻塞,car執行緒不能執行。

light執行緒負責對標誌位進行設定或者清除,car執行緒負責檢查標誌位,並根據具體的情況判斷是紅燈還是綠燈。

(2)**實現

import time,threading

#建立乙個event

event = threading.event()

def light():

count = 0 #計數器,顯示紅綠燈的秒數

event.set()

while true:

if count>5 and count<10: #進入紅燈的時間,清除綠燈的標誌位,wait()方法之後進入等待

event.clear()

print('\033[41;1mred light is on ...\033[0m')

elif count>10:

event.set()

count = 0

else:

print('\033[42;1mgreen light is on ...\033[0m')

time.sleep(1)

count += 1

def car(name):

while true:

if event.is_set(): #綠燈標誌位被設定,代表綠燈

print('[%s] running ...' % name)

time.sleep(1)

else: #代表紅燈

print('[%s] is wait the ligth to change...' % name)

event.wait()

print('\033[34;1m[%s] green light is on, starting going now \033[0m' % name)

light_th = threading.thread(target=light)

light_th.start()

car_th = threading.thread(target=car, args=('大眾',))

car_th.start()

多執行緒和同步

分幾種情況 1.其他方法前是否加了synchronized關鍵字,如果沒加,則能。2.如果這個方法內部呼叫了wait,則可以進入其他synchronized方法。3.如果其他個方法都加了synchronized關鍵字,並且內部沒有呼叫wait,則不能。4.如果其他方法是static,它用的同步鎖是當...

PV 執行緒同步和多執行緒問題

基於訊號量的執行緒同步問題,主要用到p和v操作 訊號量s是具有非負整數值的全域性變數,它只能由兩類特殊的操作來處理。這兩種操作分別稱為p和v p s 如果當s是非0的,那麼p將s 1,並且立即返回。如果開始s就是0,那麼就掛起這個執行緒等待。v s 將s加1,如果有執行緒阻塞在p操作等待s變為非0,...

多執行緒同步

synchronized 物件 其中物件相當於乙個標誌 鎖 用於判斷 同步 塊 同步的前提必須是兩個或兩個以上的執行緒,且共用同乙個鎖 同步解決了多執行緒的安全問題 弊端 多執行緒需要判斷鎖,消耗了資源 同步函式 將synchronized放在函式名前面即可 即具有同步性質 使用的鎖是this 靜態...