多任務-線程之資源競爭問題(互斥鎖)


1.在多線程中,不可避免的一個問題,就是全局變量資源存在着被多個線程調用的問題,在調用的過程中就存在着資源競爭

2.這種資源競爭是如何產生的呢?

import threading
import time

g_num = 0

def work1(num):
    global g_num
    for i in range(num):
        g_num += 1
    print("----in work1, g_num is %d---"%g_num)


def work2(num):
    global g_num
    for i in range(num):
        g_num += 1
    print("----in work2, g_num is %d---"%g_num)


print("---線程創建之前g_num is %d---"%g_num)

t1 = threading.Thread(target=work1, args=(100,))
t1.start()

t2 = threading.Thread(target=work2, args=(100,))
t2.start()

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

print("2個線程對同一個全局變量操作之后的最終結果是:%s" % g_num)

如同上述代碼,當線程執行次數有限時,全局資源不會發生大的變化,但是當高並發時,就會產生資源競爭問題,如以下代碼:

import threading
import time

g_num = 0

def work1(num):
    global g_num
    for i in range(num):
        g_num += 1
    print("----in work1, g_num is %d---"%g_num)


def work2(num):
    global g_num
    for i in range(num):
        g_num += 1
    print("----in work2, g_num is %d---"%g_num)


print("---線程創建之前g_num is %d---"%g_num)

t1 = threading.Thread(target=work1, args=(1000000,))
t1.start()

t2 = threading.Thread(target=work2, args=(1000000,))
t2.start()

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

print("2個線程對同一個全局變量操作之后的最終結果是:%s" % g_num)

3.如何解決資源競爭問題?

當存在多個線程或者進程同時調用一個全局變量資源,並且會對它進行修改時,可以采用上鎖這個方法,來解決資源競爭問題。

首先,需要了解什么叫做資源競爭?

資源競爭是指,一個全局變量資源在多個線程或者進程中被同時調用,造成該全局變量資源不斷的被修改。

解決方法:采用全局變量鎖,每當線程調用全局變量時,就將該資源上鎖,不允許被調用,只有當調用結束后才打開鎖,這里引入互斥鎖,能夠保證全局變量資源的安全。

互斥鎖的兩種狀態:鎖定/非鎖定

解決資源競爭的好處:互斥鎖保證了每次只有一個線程進行寫入操作,從而保證了多線程情況下數據的正確性。

4.互斥鎖的定義

當在請求之前,資源沒有被上鎖,那么請求並不會堵塞;如果在請求之前,是被鎖上的, 那么請求就處於一個堵塞狀態,只有當前得鎖被打開之后,才能在次上鎖。

互斥鎖的優缺點:

  優點:確保了某段關鍵代碼只能由一個線程從頭到尾完整地執行

  缺點:阻止了多線程並發執行,包含鎖的某段代碼實際上只能以單線程模式執行,效率就大大地下降了

     由於可以存在多個鎖,不同的線程持有不同的鎖,並試圖獲取對方持有的鎖時,可能會造成死鎖

# 創建鎖
mutex = threading.Lock()

# 鎖定
mutex.acquire()

# 釋放
mutex.release()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM