2010-08-11 20 views
7

Bu gibi bir şeye benzeyen bir kodum var:python: bir değişken üzerinde kilit ile başa çıkmak için zarif bir yol?

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 

olsa da çirkin bir şey. bir sürü satın alma ve yayınlama. Bu daha güzel gözüküyor:

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 

ancak bu kilit, self.logger.error bir süre alırsa (özellikle diske yazıyorsa), özellikle gerekli olandan daha uzun süre kilitli kalır. kilidi mümkün olduğunca az tutmakla daha güzel kod arasında bir orta zemin var mı?

cevap

6

Belki gibi bu mantığı ayırmak gerekir işini yapar:

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 

Ve Additionaly sen searchingLock numaranızın otomatik olarak bırakılmasının sebebi.

1

Bu size bir tane kazandıracak "self.searchingLock.release()" çok pythonic ya da bir şey değilmiş ama

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 
+0

heh clever =) Beğenmeyi seviyorum – Claudiu

+0

İlk 4 satırı başka bir işleve kolayca ayırabilirsiniz. – user37078

2

Nasıl bir sınıfta değişken & kilit sarma konusunda: Bu kadar

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) 

Ve kullanın:

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! :('   

Yorum:

Bazen ile boost :: shared_ptr kullanmak Aynı şeyi elde etmek için özel bir deleter, yani s dışında çıktığında serbest bırakılan bir kilitli değişken döndürün baş.

İlgili konular