关于Threading中Lock的理解
Lock的作用
刚开始接触python,对于线程中的锁不是很理解,错误的把Lock实现的效果当作Lock的作用。
- Lock的效果是保证同一时间只有一个线程操作公共资源(全局变量),比如互斥锁,多个线程同时加同一个锁,只有该锁释放时,其他线程才能获取该锁。至于哪个线程先获取该锁是无序的,如下。
- Lock的作用和效果不同,通过其不同的用法最终实现不同的效果。
- 锁对象(Lock)具有获取和释放两种状态,创建时处于释放状态。
- 默认创建的Lock具有阻塞作用,当Lock为一线程获取后,其他线程(包括其自身)若获取该锁,则线程阻止,不能往下运行,直到该锁释放。
- 若其他线程(包括自身)不获取该锁,则不发生阻塞作用,即阻塞作用发生在线程获取处于锁定状态的锁。
- 线程获取后的锁不一定必须释放,但若不释放,其他线程获取该锁时则发生死锁,程序假死。
互斥锁
两个线程使用同一个锁,只有一个线程运行结束后,另一个线程才能运行。
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文档,很可能是自己理解不到位。