我有一个只能通过静态方法从外部访问的类。然后,这些静态方法创建该类的一个对象以在该方法中使用,然后它们返回并且该对象可能被销毁。该类是几个配置文件的 getter/setter,现在我需要在对配置文件的访问上放置线程锁。
由于我有几种不同的静态方法,它们都需要对配置文件进行读/写访问,而这些配置文件都在该方法的范围内创建对象,因此我正在考虑在对象构造函数内部完成锁获取,然后释放在析构函数中。
我的同事表示担心,如果发生什么事情,这可能会让类(class)永远被锁定。他还提到了关于垃圾收集器如何调用 python 中的析构函数,但我们对 python 都比较陌生,所以这是一个未知数。
这是一个合理的解决方案还是我应该在每个方法本身中锁定/解锁?
Class A():
rateLock = threading.RLock()
chargeLock = threading.RLock()
@staticmethod
def doZStuff():
a = A()
a.doStuff('Z')
@staticmethod
def doYStuff():
a = A()
a.doStuff('Y')
@synchronized(lock)
def doStuff(self, type):
if type == 'Z':
otherstuff()
elif type == 'B':
evenmorestuff()
是否有可能让它在 doStuff()
上的装饰器上以这种方式工作,而不是 doZStuff()
更新
谢谢大家的回答。我面临的问题主要是由于异步访问我的模块并没有真正意义,但这只是 API 的一部分。通过 API 访问我们的内容的团队提示并发问题。所以我不需要完美的解决方案,我只是想做到这一点,这样他们就不能让我们这边崩溃或取回垃圾数据
最佳答案
Class A():
rateLock = threading.RLock()
chargeLock = threading.RLock()
def doStuff(self,ratefile,chargefile):
with A.rateLock:
with open(ratefile) as f:
# ...
with A.chargeLock:
with open(chargefile) as f:
# ...
使用with statement将保证 (R)Lock 成对获取和释放。即使 with block 内发生异常,也会调用release。
您可能还需要考虑将锁放置在文件访问 block 周围 with open(...) as ...
尽可能紧密,以便锁的持有时间不会超过必要的。
最后,a=A()的创建和垃圾回收不会影响锁
如果(如上所述)锁是类属性(而不是实例属性)。类属性位于 A.__dict__
中,而不是 a.__dict__
中。因此,在 A 本身被垃圾回收之前,锁不会被垃圾回收。
关于python - python中构造函数/析构函数中的线程锁定/解锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3712388/