Python 条件性 "With" 锁设计
我正在尝试使用“with”语句来进行一些共享锁定。
def someMethod(self, hasLock = False):
with self.my_lock:
self.somethingElse(hasLock=True)
def somethingElse(self, hasLock = False):
#I want this to be conditional...
with self.my_lock:
print 'i hate hello worlds"
这样理解吗?我基本上只想在我还没有锁的时候才使用“with”。
除了能做到这一点,这样的设计会不好吗?我是不是应该自己去获取和释放锁?
5 个回答
2
使用with语句比单纯使用acquire()
和release()
函数要好。这是因为如果出现错误,锁会自动释放。
8
在Python中,or
是一个“短路”操作,这意味着你可以让锁的使用变得有条件:
def somethingElse(self, hasLock = False):
#I want this to be conditional...
with hasLock or self.my_lock:
print 'i hate hello worlds'
不过,这事并没有那么简单,因为布尔值(也就是True或False)不能直接作为with
语句的返回值。你需要创建一个类,并定义__enter__
和__exit__
这两个方法,来包装布尔值True
。
下面是一个可能的实现方式,不过我还没有测试过。
from contextlib import contextmanager
@contextmanager
def withTrue():
yield True
def withbool(condition):
if condition:
return withTrue()
return False
def somethingElse(self, hasLock = False):
with withbool(hasLock) or self.my_lock():
print 'i hate hello worlds'
为了这么简单的事情,写这么多代码确实有点多余,所以使用RLock的解决方案看起来更好。不过,这种方法在其他情况下可能会有用。
64
你可以使用一个叫做 threading.RLock
的东西,它是可重入的,这意味着同一个线程可以多次获得它。
http://docs.python.org/library/threading.html#rlock-objects
为了更清楚,RLock
是在 with
语句中使用的,就像你示例代码里那样:
lock = threading.RLock()
def func1():
with lock:
func2()
def func2():
with lock: # this does not block even though the lock is acquired already
print 'hello world'
至于这是否算是糟糕的设计,我们需要更多的信息。为什么这两个函数都需要获取这个锁?func2
是在什么情况下被其他东西调用,而不是被 func1
调用的?