我有一个只能通过静态方法从外部访问的类。这些静态方法然后创建一个类的对象在方法中使用,然后它们返回并且对象可能被销毁。现在需要一对getter锁来访问config/setter类的文件。在
由于我有几个不同的静态方法,它们都需要对配置文件的读/写访问权限,这些文件都是在方法范围内创建对象的,所以我考虑在对象构造函数内部完成锁获取,然后在析构函数中释放。在
我的同事表示担心,如果发生什么事情,可能会导致类永远锁定。他还提到了关于垃圾收集器如何调用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()
上而不是{
更新
谢谢大家的回答。我所面临的问题主要是因为异步访问我的模块没有实际意义,但这只是API的一部分。通过API访问我们的东西的团队抱怨并发性问题。所以我不需要完美的解决方案,我只是想让他们不会让我们这边崩溃,也不会拿回垃圾数据
但是,如果你必须在构造函数和析构函数中获取和释放锁,那么你真的,真的,真的应该给你的设计另一个机会。你应该改变你的基本假设。在
在任何应用中:“锁”应该总是保持很短的时间-尽可能短。这意味着-在所有情况下,您将以释放锁的相同方法获取锁。在
几乎不应该有任何理由以RAII方式锁定/解锁对象。这不是它的本意;)
我给你举个例子:你管理一些资源,这些资源可以一次从多个线程读取,但是只有一个线程可以写入它们。在
在一个“幼稚”的实现中,每个对象都有一个锁,每当有人想写它时,你就会锁定它。当你决定写多个线程时,我们会很好地把它写出来,,然后我们就要写多个线程了。在
但是请理解锁,互斥-所有这些原语的创建只是为了同步你的源代码的几行。因此,与使锁成为可写对象的一部分不同,您只有一个非常短的时间内真正需要它的锁。你必须在你的界面上投入更多的时间和思想。但是,锁/互斥锁的“保持”时间从来不会超过几微秒。在
你对垃圾收集是正确的,所以这不是一个好主意。 查看decorator,用于编写同步函数。在
示例:http://code.activestate.com/recipes/465057-basic-synchronization-decorator/
编辑 我还不能百分之百确定你的想法,所以我的建议可能是错误的:
使用with statement将保证成对获取和释放(R)锁。即使with块中发生异常,也将调用发布。在
您可能还需要考虑将锁尽可能紧密地放在文件访问块
with open(...) as ...
周围,这样锁的保留时间不会超过需要的时间。在最后,a=a()的创建和垃圾回收不会影响锁 如果(如上所述)锁是类属性(与实例属性相反)。类属性位于
A.__dict__
,而不是a.__dict__
。因此,在A本身被垃圾回收之前,锁不会被垃圾回收。在相关问题 更多 >
编程相关推荐