[英]python: elegant way to deal with lock on a variable?
I have code that looks like something like this: 我的代码看起来像这样:
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
it's kind of ugly, though. 但它有点难看。 lots of acquires and releases. 大量的获取和发布。 this looks prettier: 这看起来更漂亮:
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
but this keeps the lock longer than strictly necessary, espcially if self.logger.error
takes a while (like if it writes to disk, which it does). 但是这会使锁定的时间超过严格必要的时间,特别是如果self.logger.error
需要一段时间(就像它写入磁盘一样)。 is there any middle ground between holding the lock as little as possible but having prettier code? 是否有尽可能少的锁定之间的中间地带,但有更漂亮的代码?
Maybe you need to separate this logic like: 也许你需要将这个逻辑分开:
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
And additionaly you telling your searchingLock
the reason to release it automaticaly. 另外你告诉你的searchingLock
锁定自动释放它的原因。
How about wrapping the variable & lock in a class: 如何在类中包装变量和锁:
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)
And use as this: 并使用如下:
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! :('
Comment: 评论:
I sometimes use boost::shared_ptr with a custom deleter to achieve the same thing, ie return an unlocked variable that's released when it goes out of scope. 我有时会使用boost :: shared_ptr和自定义删除器来实现相同的功能,即返回一个在超出范围时释放的解锁变量。
This will save you one " self.searchingLock.release()
" Guess it's not very pythonic or anything but it does the job 这将节省你一个“ 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.