简体   繁体   English

python:处理变量锁定的优雅方式?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM