關於Threading中Lock的理解

關於Threading中Lock的理解

Lock的做用

剛開始接觸python,對於線程中的鎖不是很理解,錯誤的把Lock實現的效果看成Lock的做用。python

  • Lock的效果是保證同一時間只有一個線程操做公共資源(全局變量),好比互斥鎖,多個線程同時加同一個鎖,只有該鎖釋放時,其餘線程才能獲取該鎖。至於哪一個線程先獲取該鎖是無序的,以下。
  • Lock的做用和效果不一樣,經過其不一樣的用法最終實現不一樣的效果。
    1. 鎖對象(Lock)具備獲取和釋放兩種狀態,建立時處於釋放狀態。
    2. 默認建立的Lock具備阻塞做用,當Lock爲一線程獲取後,其餘線程(包括其自身)若獲取該鎖,則線程阻止,不能往下運行,直到該鎖釋放。
    3. 若其餘線程(包括自身)不獲取該鎖,則不發生阻塞做用,即阻塞做用發生在線程獲取處於鎖定狀態的鎖。
    4. 線程獲取後的鎖不必定必須釋放,但若不釋放,其餘線程獲取該鎖時則發生死鎖,程序假死。

互斥鎖

兩個線程使用同一個鎖,只有一個線程運行結束後,另外一個線程才能運行。app

import threading
import time

total = 0
mutex = threading.Lock()


def sum_num(num):
    mutex.acquire() #獲取鎖
    for i in range(num):
        global total
        total += 1
    print(f'{threading.current_thread()}sum num is: {total}.')
    mutex.release() #釋放鎖

if __name__ == '__main__':
    thread_list = []
    for num in [1000000 for i in range(10)]:
        multi_thread = threading.Thread(target=sum_num,args=(num,),)
        multi_thread.start()
        thread_list.append(multi_thread)

    # 主線程等待子線程運行結束後運行打印
    for t in thread_list:
        t.join()
    print('total is:', total)

示例

建立兩個線程,其中一個線程輸出1-52,另一個輸出A-Z,要求輸出的格式以下:ui

12A 34B 56C ..... 5152Z線程

使用一個鎖

import threading, time

def num():
    for i in range(1,53,2):
        lock.acquire()
        print(str(i)+str(i+1), end='')

def alpha():
    for i in range(65, 91):
        time.sleep(0.000001)
        print(chr(i))
        lock.release()

if __name__ == '__main__':
    lock = threading.Lock()

    sn = threading.Thread(target=num)
    sa = threading.Thread(target=alpha)

    sn.start()
    sa.start()

使用多個鎖

import threading, time
alpha_lock = threading.Lock()
num_lock = threading.Lock()

def print_num():
    num_lock.acquire() #先加鎖,當輸出2本身在獲取鎖時必須等待另外一進程釋放
    for i in range(1, 53, 2):

        print(str(i)+str(i + 1), end='')

        num_lock.acquire()
        alpha_lock.release()

def print_alpla():

    for w in range(ord('A'), ord('Z') + 1,):

        print(chr(w))

        num_lock.release()
        alpha_lock.acquire()


if __name__ == '__main__':
    num_thread = threading.Thread(target=print_num,)
    alpha_thread = threading.Thread(target=print_alpla)

    alpha_lock.acquire()
    num_thread.start()
    alpha_thread.start()

重點是進程再次獲取本身已經獲取到的鎖時必須等待另外一進程釋放code

收穫

  • 遇到不懂的問題除了谷歌外,多看python文檔,極可能是本身理解不到位。
相關文章
相關標籤/搜索