1. 程式人生 > >關於Threading中Lock的理解

關於Threading中Lock的理解

關於Threading中Lock的理解

Lock的作用

剛開始接觸python,對於執行緒中的鎖不是很理解,錯誤的把Lock實現的效果當作Lock的作用。

  • Lock的效果是保證同一時間只有一個執行緒操作公共資源(全域性變數),比如互斥鎖,多個執行緒同時加同一個鎖,只有該鎖釋放時,其他執行緒才能獲取該鎖。至於哪個執行緒先獲取該鎖是無序的,如下。
  • Lock的作用和效果不同,通過其不同的用法最終實現不同的效果。
    1. 鎖物件(Lock)具有獲取和釋放兩種狀態,建立時處於釋放狀態。
    2. 預設建立的Lock具有阻塞作用,當Lock為一執行緒獲取後,其他執行緒(包括其自身)若獲取該鎖,則執行緒阻止,不能往下執行,直到該鎖釋放。
    3. 若其他執行緒(包括自身)不獲取該鎖,則不發生阻塞作用,即阻塞作用發生線上程獲取處於鎖定狀態的鎖。
    4. 執行緒獲取後的鎖不一定必須釋放,但若不釋放,其他執行緒獲取該鎖時則發生死鎖,程式假死。

互斥鎖

兩個執行緒使用同一個鎖,只有一個執行緒執行結束後,另一個執行緒才能執行。

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,要求輸出的格式如下:

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

import threading, time

alpha_lock = threading.Lock()
num_lock = threading.Lock()

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

        print(str(i), end='')
        if i % 2 == 0:
            num_lock.acquire()
            alpha_lock.release()

def print_alpla():

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

        time.sleep(0.000001) #等待數字先輸出
        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)

    num_thread.start()
    alpha_thread.start()

重點是程序再次獲取自己已經獲取到的鎖時必須等待另一程序釋放

收穫

  • 遇到不懂的問題除了谷歌外,多看python文件,很可能是自己理