我的代码看起来像这样:
def startSearching(self):
self.searchingLock.acquire()
searching = self.searching
if self.searching:
self.searchingLock.release()
self.logger.error("Already searching!")
return False
self.searching = True
self.searchingLock.release()
#some more init code, then start the thread which
#constantly checks self.searching to determine when to stop
但是,这有点难看。大量的获取和发布。这看起来更漂亮:
def startSearching(self):
with self.searchingLock:
if self.searching:
self.logger.error("Already searching!")
return False
self.searching = True
#some more init code, then start the thread which
#constantly checks self.searching to determine when to stop
但这会使锁定的时间长于严格必要的时间,特别是如果self.logger.error
需要一段时间(就像它写入磁盘一样)。在尽可能少地拿着锁之间是否有任何中间地带,但是有更漂亮的代码?
答案 0 :(得分:6)
也许你需要将这个逻辑分开:
def initSearch(self):
with self.searchingLock:
if self.searching : raise SearchingError('AlreadySearching')
self.searching = True
def startSearching(self):
try: self.initSearch()
except SearchingError as error :
self.logger.error(error.message)
return False
#some more init code, then start the thread which
#constantly checks self.searching to determine when to stop
另外,您告诉searchingLock
自动释放它的原因。
答案 1 :(得分:2)
如何包装变量&锁定课程:
class LockedVariable(object):
def __init__(self, value, lock=None):
self._value = value
self._lock = lock if lock else threading.RLock()
self._locked = false:
@property
def locked(self):
return self._locked
def assign(self, value):
with self:
self._value = value
def release():
self._locked = False
return self._lock.release()
def __enter__(self):
self._lock.__enter__()
self._locked = True
return self._value
def __exit__(self, *args, **kwargs):
if self._locked:
self._locked = False
return self._lock.__exit__(*args, **kwargs)
并使用:
locked_dict = LockedVariable({})
with locked_dict as value:
value['answer'] = 42
if locked_dict.locked:
locked_dict.release()
print 'eureka! :)'
return
if locked_dict.locked:
print 'bahh! :('
注释:
我有时会将boost :: shared_ptr与自定义删除器一起使用来实现相同的功能,即返回一个在超出范围时释放的未锁定变量。
答案 2 :(得分:1)
这会为你节省一个“self.searchingLock.release()
”。猜猜它不是非常pythonic或任何东西,但它做的工作
def startSearching(self):
self.searchingLock.acquire()
already_searching = self.searching
self.searching = True # Since it'll be true in both scenarios
self.searchingLock.release()
if already_searching:
self.logger.error("Already searching!")
return not already_searching