目录
  • 前言
  • 方式一:使用try/finally,确保锁肯定会被释放。
  • 方式二:with语句避免使用try/finally。
  • 总结

前言

当有多个线程,且它们同时访问同一资源时,需要考虑如何避免线程冲突。解决办法是使用线程锁。锁由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线程锁内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!