多工08 互斥鎖

2021-08-27 03:01:48 字數 1708 閱讀 5345

當多個執行緒幾乎同時修改某乙個共享資料的時候,需要進行同步控制

執行緒同步能夠保證多個執行緒安全訪問競爭資源,最簡單的同步機制是引入互斥鎖。

互斥鎖為資源引入乙個狀態:鎖定/非鎖定

某個執行緒要更改共享資料時,先將其鎖定,此時資源的狀態為「鎖定」,其他執行緒不能更改;直到該執行緒釋放資源,將資源的狀態變成「非鎖定」,其他的執行緒才能再次鎖定該資源。互斥鎖保證了每次只有乙個執行緒進行寫入操作,從而保證了多執行緒情況下資料的正確性。

threading模組中定義了lock類,可以方便的處理鎖定:

# 建立鎖

mutex = threading.lock()

# 鎖定

mutex.acquire()

# 釋放

mutex.release()

注意:

使用互斥鎖完成2個執行緒對同乙個全域性變數各加100萬次的操作

import threading

import time

g_num = 0

def test1(num):

global g_num

for i in range(num):

mutex.acquire() # 上鎖

g_num += 1

mutex.release() # 解鎖

print("---test1---g_num=%d"%g_num)

def test2(num):

global g_num

for i in range(num):

mutex.acquire() # 上鎖

g_num += 1

mutex.release() # 解鎖

print("---test2---g_num=%d"%g_num)

# 建立乙個互斥鎖

# 預設是未上鎖的狀態

mutex = threading.lock()

# 建立2個執行緒,讓他們各自對g_num加1000000次

p1 = threading.thread(target=test1, args=(1000000,))

p1.start()

p2 = threading.thread(target=test2, args=(1000000,))

p2.start()

# 等待計算完成

while len(threading.enumerate()) != 1:

time.sleep(1)

print("2個執行緒對同乙個全域性變數操作之後的最終結果是:%s" % g_num)

執行結果:

---test1---g_num=1909909

---test2---g_num=2000000

2個執行緒對同乙個全域性變數操作之後的最終結果是:2000000

可以看到最後的結果,加入互斥鎖後,其結果與預期相符。

當乙個執行緒呼叫鎖的acquire()方法獲得鎖時,鎖就進入「locked」狀態。

每次只有乙個執行緒可以獲得鎖。如果此時另乙個執行緒試圖獲得這個鎖,該執行緒就會變為「blocked」狀態,稱為「阻塞」,直到擁有鎖的執行緒呼叫鎖的release()方法釋放鎖之後,鎖進入「unlocked」狀態。

執行緒排程程式從處於同步阻塞狀態的執行緒中選擇乙個來獲得鎖,並使得該執行緒進入執行(running)狀態。

鎖的好處:

鎖的壞處:

Linux 多工程式設計 多工的同步與互斥

現代作業系統基本都是多工作業系統,即同時有大量可排程實體在執行。在多工作業系統中,同時執行的多個任務可能 這兩種情形是多工程式設計中遇到的最基本的問題,也是多工程式設計中的核心問題,同步和互斥就是用於解決這兩個問題的。互斥 是指散步在不同任務之間的若干程式片斷,當某個任務執行其中乙個程式片段時,其它...

Linux 多工程式設計 執行緒同步與互斥 讀寫鎖

讀寫鎖基本原理 當有乙個執行緒已經持有互斥鎖時,互斥鎖將所有試圖進入臨界區的執行緒都阻塞住。但是考慮一種情形,當前持有互斥鎖的執行緒只是要讀訪問共享資源,而同時有其它幾個執行緒也想讀取這個共享資源,但是由於互斥鎖的排它性,所有其它執行緒都無法獲取鎖,也就無法讀訪問共享資源了,但是實際上多個執行緒同時...

多工的同步與互斥

現代作業系統基本都是多工作業系統,即同時有大量可排程實體在執行。在多工作業系統中,同時執行的多個任務可能 這兩種情形是多工程式設計中遇到的最基本的問題,也是多工程式設計中的核心問題,同步和互斥就是用於解決這兩個問題的。互斥 是指散步在不同任務之間的若干程式片斷,當某個任務執行其中乙個程式片段時,其它...