前言
当有多个线程,且它们同时访问同一资源时,需要考虑如何避免线程冲突。解决办法是使用线程锁。锁由Python的threading模块提供,并且它最多被一个线程所持有。当一个线程试图获取一个已经锁在资源上的锁时,该线程通常会暂停运行,直到这个锁被释放。看看下面的不具备锁功能的例子:
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# Author: LiveEveryDay
import threading
total = 0
def update_total(amount):
global total
total += amount
print(total)
if __name__ == '__main__':
for i in range(10):
my_thread = threading.Thread(target=update_total, args=(5,))
my_thread.start()
''' ------ Running Results ------
510
15
20
25
30
3540
45
50
'''
如果往以上代码添加 time.sleep 函数并给出不同长度的时间,可能会让这个例子更有意思。无论如何,这里的问题是,一个线程可能已经调用 update_total 函数并且还没有更新完成,此时另一个线程也有可能调用它并且尝试更新内容。根据操作执行顺序的不同,该值可能只被增加一次。
给它添加锁后:
方式一:使用try/finally,确保锁肯定会被释放。
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# Author: LiveEveryDay
import threading
total = 0
lock = threading.Lock()
def update_total(amount):
global total
lock.acquire()
try:
total += amount
finally:
print(total)
lock.release()
if __name__ == '__main__':
for i in range(10):
my_thread = threading.Thread(target=update_total, args=(5,))
my_thread.start()
''' ------ Running Results ------
5
10
15
20
25
30
35
40
45
50
'''
如上,在我们做任何处理之前就获取锁。然后尝试更新 total 的值,最后打印出 total 的当前值并释放锁。
方式二:with语句避免使用try/finally。
事实上,我们可以使用 Python 的 with 语句避免使用 try/finally 这种较为繁琐的语句:
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# Author: LiveEveryDay
import threading
total = 0
lock = threading.Lock()
def update_total(amount):
global total
with lock:
total += amount
print(total)
if __name__ == '__main__':
for i in range(10):
my_thread = threading.Thread(target=update_total, args=(5,))
my_thread.start()
''' ------ Running Results ------
5
10
15
20
25
30
35
40
45
50
'''
总结
到此这篇关于Python中线程锁的使用介绍的文章就介绍到这了,更多相关Python线程锁内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!