关于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)

使用多个锁

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文档,很可能是自己理解不到位。
08-27 20:05