[Python]使用Lock避免threading競速導致數據的不一致性的問題

閱讀時間約 3 分鐘

避免 thread 競速(Race Condition)是多執行緒編程中常見的挑戰之一。

Race Condition 發生在多個執行緒同時訪問修改共享資源時,因為執行緒之間的執行順序無法預測,可能會導致數據的不一致性或意外行為。

本文主要介紹如何使用Lock來避免此狀況出現。


首先先看沒有Lock的範例。

來模擬Race Condition的現象,假設沒有這個現象,最後shared_counter數值應該是要10000,10個執行緒疊加的結果才對。

import threading
import time

# 定義一個共享資源
shared_counter = 0

def increment_counter():
global shared_counter
for _ in range(1000):
temp = shared_counter
time.sleep(0.00001) # 模擬執行緒切換
shared_counter = temp + 1

# 建立多個執行緒
threads = []
for _ in range(10):
thread = threading.Thread(target=increment_counter)
threads.append(thread)
thread.start()

# 等待所有執行緒完成
for thread in threads:
thread.join()

print(f"Final counter value: {shared_counter}")

但數值卻在1000左右亂跑,而且不固定數值,這情況就是Race Condition所造成的,A執行緒跟B執行緒在互跑時,互相覆蓋了對方的結果。

raw-image

使用Lock的範例

import threading
import time

# 定義一個共享資源
shared_counter = 0

# 建立一個 Lock
lock = threading.Lock()

def increment_counter():
global shared_counter
for _ in range(1000):
# 使用 Lock 保護共享資源
with lock:
shared_counter += 1
time.sleep(0.00001) # 模擬執行緒切換

# 建立多個執行緒
threads = []
for _ in range(10):
thread = threading.Thread(target=increment_counter)
threads.append(thread)
thread.start()

# 等待所有執行緒完成
for thread in threads:
thread.join()

print(f"Final counter value: {shared_counter}")

不管執行了幾次,結果一樣都是我們預期的1000。

raw-image
  • Lock 機制
    • lock = threading.Lock() 創建了一個鎖(Lock),以確保同一時間內只有一個執行緒可以進入 with lock: 區塊來操作 shared_counter
    • 當一個執行緒進入 with lock: 區塊時,其他執行緒會被阻塞在該區塊外,直到鎖被釋放。
  • 避免 Race Condition
    • 使用 Lock 後,確保了 shared_counter 的讀取、遞增和寫回操作,這樣可以避免多個執行緒同時修改 shared_counter,從而避免 Race Condition 的發生。



112會員
172內容數
本業是影像辨識軟體開發,閒暇時間進修AI相關內容,將學習到的內容寫成文章分享。
留言0
查看全部
發表第一個留言支持創作者!
螃蟹_crab的沙龍 的其他內容
呈上篇,若是在大型系統中使用,重複被調用時,在每次紀錄時都會創建一個新的 FileHandler,這會導致日誌處理器不斷累積,從而使日誌重複記錄。 [Python]使用logging創建兩個以上的日誌紀錄 使用__new__的方法來避免重複調用 改良後 setup_logger 方法中創建一
在處理數據時,最可能會遇到數據中含有None的時候,若沒有處理就進行運算就會造成程式崩潰或者報錯 數據中含有None input_list = [(42, 292), (28, 296), (999, 92), (993, 46), (219, 4), (279, 2), (None, None
在檢查列表中含有tuple的座標點時,若要給其他演算法做運算時若有其中有tuple有空值時,就會報錯。 本文主要介紹兩種方法可以檢查是否有空值 程式範例1 positon_list =[(42,123),(None,None),(22,11)] for cord in positon_lis
對於程式卡頓的問題,如何分析程式碼占用多少記憶體,如何釋放或改寫,可以先用python內建的tracemalloc模組來追蹤 Python 分配的記憶體區塊。 本文將介紹最簡單的用法,來分析一段程式碼占用了多少記憶體。 結果呈現 印出當前使用的記憶體,與峰值記憶體使用量。 程式範例 i
在離線環境需要安裝Python套件時就相當的麻煩,需要先下載好套件包,在打指令安裝,若套件數量一多時就會相當麻煩。 本文將介紹如何利用兩行指令快速的安裝整個資料夾的套件。
在讀取檔案時,最怕路徑的問題,常常會有路徑錯誤造成的異常報錯。 為了避免諸如此類的問題發生,明白程式的當前目錄與檔案的路徑是很重要的。 可以利用os 模組是 Python 中的一個標準庫,提供了許多與操作系統的功能。 以下是一些常用的 os 模組基本操作及其範例: 1. os.getcwd
呈上篇,若是在大型系統中使用,重複被調用時,在每次紀錄時都會創建一個新的 FileHandler,這會導致日誌處理器不斷累積,從而使日誌重複記錄。 [Python]使用logging創建兩個以上的日誌紀錄 使用__new__的方法來避免重複調用 改良後 setup_logger 方法中創建一
在處理數據時,最可能會遇到數據中含有None的時候,若沒有處理就進行運算就會造成程式崩潰或者報錯 數據中含有None input_list = [(42, 292), (28, 296), (999, 92), (993, 46), (219, 4), (279, 2), (None, None
在檢查列表中含有tuple的座標點時,若要給其他演算法做運算時若有其中有tuple有空值時,就會報錯。 本文主要介紹兩種方法可以檢查是否有空值 程式範例1 positon_list =[(42,123),(None,None),(22,11)] for cord in positon_lis
對於程式卡頓的問題,如何分析程式碼占用多少記憶體,如何釋放或改寫,可以先用python內建的tracemalloc模組來追蹤 Python 分配的記憶體區塊。 本文將介紹最簡單的用法,來分析一段程式碼占用了多少記憶體。 結果呈現 印出當前使用的記憶體,與峰值記憶體使用量。 程式範例 i
在離線環境需要安裝Python套件時就相當的麻煩,需要先下載好套件包,在打指令安裝,若套件數量一多時就會相當麻煩。 本文將介紹如何利用兩行指令快速的安裝整個資料夾的套件。
在讀取檔案時,最怕路徑的問題,常常會有路徑錯誤造成的異常報錯。 為了避免諸如此類的問題發生,明白程式的當前目錄與檔案的路徑是很重要的。 可以利用os 模組是 Python 中的一個標準庫,提供了許多與操作系統的功能。 以下是一些常用的 os 模組基本操作及其範例: 1. os.getcwd
你可能也想看
Thumbnail
1.加權指數與櫃買指數 週五的加權指數在非農就業數據開出來後,雖稍微低於預期,但指數仍向上噴出,在美股開盤後於21500形成一個爆量假突破後急轉直下,就一路收至最低。 台股方面走勢需觀察週一在斷頭潮出現後,週二或週三開始有無買單進場支撐,在沒有明確的反轉訊號形成前,小夥伴盡量不要貿然抄底,或是追空
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
PyInstaller 是一個強大的工具,可以將 Python 程式碼打包成獨立的可執行檔案,讓你的程式可以在沒有 Python 解釋器的情況下運行。這對於分享和分發你的 Python 應用程式非常有用。以下是使用 PyInstaller 的基本步驟:
使用Python的Threading模組設計一個能夠在背景待命的程式,並在等待5秒後自動結束。我們將使用執行緒來執行背景任務,並使用定時等待來控制程式的結束時間。這種方法適用於不依賴於特定按鍵事件的情況,而是在固定的時間後自動退出程式。
在這篇教學中,我們將介紹如何使用Python的openpyxl套件將資料寫入Excel文件。openpyxl是一個功能強大的函式庫,可以讓我們輕鬆地處理Excel文件。
在這篇教學中,我們將介紹如何使用Python的openpyxl模組來讀取Excel文件中的資料。openpyxl是一個功能強大的函式庫,可以讓我們輕鬆地處理Excel文件。
安裝 pyautogui 在開始之前,我們需要先安裝 pyautogui 模塊。
這篇教學文章將介紹如何使用 OpenAI 的 GPT-3 模型來建立一個簡單的聊天機器人。
安裝 pyautogui 在開始之前,我們需要先安裝 pyautogui 模塊。你可以在終端或命令提示字元中輸入以下命令來安裝它: 1.移動滑鼠 2.模擬滑鼠點擊 3.模擬滑鼠拖曳 4.捲動滑鼠
使用 pyautogui 套件來取得所有正在視窗 (windows)。
Thumbnail
初玩python時常用pip安裝各式各樣的套件下來,而這些套件在本機中是以全域的方式安裝。假設今天需要接手別人的專案,所用的套件版本不相容,對於這些仰賴的套件(依賴dependencies)進行管理跟切分就成了一個課題。
Thumbnail
在Python中使用MySQLdb的起手式大概長這樣。記得execute裡面的SQL語法一定要加上冒號,否則會出錯。我也在這個愚蠢的錯誤上跌倒過。編碼問題是資料庫管理中常見的問題,編碼包含又包含了兩個部份,collation和character set。
Thumbnail
1.加權指數與櫃買指數 週五的加權指數在非農就業數據開出來後,雖稍微低於預期,但指數仍向上噴出,在美股開盤後於21500形成一個爆量假突破後急轉直下,就一路收至最低。 台股方面走勢需觀察週一在斷頭潮出現後,週二或週三開始有無買單進場支撐,在沒有明確的反轉訊號形成前,小夥伴盡量不要貿然抄底,或是追空
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
PyInstaller 是一個強大的工具,可以將 Python 程式碼打包成獨立的可執行檔案,讓你的程式可以在沒有 Python 解釋器的情況下運行。這對於分享和分發你的 Python 應用程式非常有用。以下是使用 PyInstaller 的基本步驟:
使用Python的Threading模組設計一個能夠在背景待命的程式,並在等待5秒後自動結束。我們將使用執行緒來執行背景任務,並使用定時等待來控制程式的結束時間。這種方法適用於不依賴於特定按鍵事件的情況,而是在固定的時間後自動退出程式。
在這篇教學中,我們將介紹如何使用Python的openpyxl套件將資料寫入Excel文件。openpyxl是一個功能強大的函式庫,可以讓我們輕鬆地處理Excel文件。
在這篇教學中,我們將介紹如何使用Python的openpyxl模組來讀取Excel文件中的資料。openpyxl是一個功能強大的函式庫,可以讓我們輕鬆地處理Excel文件。
安裝 pyautogui 在開始之前,我們需要先安裝 pyautogui 模塊。
這篇教學文章將介紹如何使用 OpenAI 的 GPT-3 模型來建立一個簡單的聊天機器人。
安裝 pyautogui 在開始之前,我們需要先安裝 pyautogui 模塊。你可以在終端或命令提示字元中輸入以下命令來安裝它: 1.移動滑鼠 2.模擬滑鼠點擊 3.模擬滑鼠拖曳 4.捲動滑鼠
使用 pyautogui 套件來取得所有正在視窗 (windows)。
Thumbnail
初玩python時常用pip安裝各式各樣的套件下來,而這些套件在本機中是以全域的方式安裝。假設今天需要接手別人的專案,所用的套件版本不相容,對於這些仰賴的套件(依賴dependencies)進行管理跟切分就成了一個課題。
Thumbnail
在Python中使用MySQLdb的起手式大概長這樣。記得execute裡面的SQL語法一定要加上冒號,否則會出錯。我也在這個愚蠢的錯誤上跌倒過。編碼問題是資料庫管理中常見的問題,編碼包含又包含了兩個部份,collation和character set。