Python 3.x 锁是否需要声明为全局锁?
Python3.xPython 3.x 锁是否需要声明为全局锁?,python-3.x,Python 3.x,Python3.x import threading lock = threading.Lock() counter = 0 def update_counter(): global counter lock.acquire() counter += 1 lock.release() # starts threads, target update_counter 锁也必须是全局的吗?如果没有,由于未定义本地锁,它如何不导致错误 谢谢锁保护某些资源,并且通
import threading
lock = threading.Lock()
counter = 0
def update_counter():
global counter
lock.acquire()
counter += 1
lock.release()
# starts threads, target update_counter
锁也必须是全局的吗?如果没有,由于未定义本地锁,它如何不导致错误
谢谢锁保护某些资源,并且通常与资源的作用域相同。在您的情况下,您正在保护一个全局计数器,因此锁也必须是全局的。所有访问该资源的线程都必须使用相同的锁,因此在函数本身中创建私有锁不会有任何好处——其他线程都不会看到它 有些应用程序使用单个锁来保护所有共享资源(当然是细粒度锁)。但您也可以对数据保持锁定(细粒度锁定)。细粒度锁定的一个示例是:
class MyCounter:
def __init__(self):
self.lock = threading.Lock()
self.value = 0
def increment(self):
with self.lock:
self.value += 1
现在,
MyCounter
的每个实例都有一个锁并独立运行。要直接回答这个问题,需要声明counter
全局,而lock
不需要声明的原因是您正在重新分配给counter
(使用counter+=1
)而您只在lock
上调用方法。对于变量的引用,如果不存在局部变量,Python将在封闭范围内查找,直到找到匹配项为止。在本例中,它在全局范围内找到它。对于变量赋值,Python将假定变量为本地变量,除非明确声明为其他变量(使用global
或nonlocal
)。尝试时是否遇到错误?旁注:不要手动调用acquire
和release
。尽可能使用带有
语句的;它是异常安全的,避免了忘记正确匹配acquire
和release
调用的可能性?在您的示例中,lock
应该是全局的,就像您编写的一样,因为您保护的资源是全局的。使用该资源的所有代码都需要获取1锁才能工作。如果需要,还可以在函数中声明全局锁
,并在本地命名空间中保存额外的查找。但通常,如果不重新绑定变量,则不需要global
关键字。