2013-05-24 4 views
5

Ich bin mit einem Python 3-Sequenz wie folgt aus:Python Schloss mit-Anweisung und Timeout

lock = threading.Lock() 
res = lock.acquire(timeout=10) 
if res: 
    # do something .... 
    lock.release() 
else: 
    # do something else ... 

Ich würde es vorziehen, eine mit-Anweisung anstelle von expliziten „acquire“ und „Release“ zu verwenden, aber ich don Ich weiß nicht, wie man den Timeout-Effekt bekommt.

+0

Es sieht nicht so aus, als könnten Sie das tun. – Blender

+0

[dies] (http://stackoverflow.com/questions/8392640/how-to-implement-a-lock-with-a-timeout-in-python-2-7) könnte helfen – shx2

+0

Es sieht nicht wie was aus Ich will ;-). – Tsf

Antwort

5

Sie dies mit einem Kontext-Manager ziemlich leicht tun können:

import threading 
from contextlib import contextmanager 

@contextmanager 
def acquire_timeout(lock, timeout): 
    result = lock.acquire(timeout=timeout) 
    yield result 
    if result: 
     lock.release() 


# Usage: 
lock = threading.Lock() 

with acquire_timeout(lock, 2) as acquired: 
    if acquired: 
     print('got the lock') 
     # do something .... 
    else: 
     print('timeout: lock not available') 
     # do something else ... 

* Hinweis: Dies wird nicht in Python 2.x funktionieren, da es zu Lock.acquire

kein timeout Argument ist
1

Etwas schönere Version:

import threading 
from contextlib import contextmanager 


class TimeoutLock(object): 
    def __init__(self): 
     self._lock = threading.Lock() 

    def acquire(self, blocking=True, timeout=-1): 
     return self._lock.acquire(blocking, timeout) 

    @contextmanager 
    def acquire_timeout(self, timeout): 
     result = self._lock.acquire(timeout=timeout) 
     yield result 
     if result: 
      self._lock.release() 

    def release(self): 
     self._lock.release() 

# Usage: 
lock = TimeoutLock() 

with lock.acquire_timeout(3) as result: 
    if result: 
     print('got the lock') 
     # do something .... 
    else: 
     print('timeout: lock not available') 
     # do something else ... 

Es scheint Sie nicht threading.Lock Unterklasse kann, so Ich musste stattdessen eine Wrapper-Klasse erstellen.

+0

Schön! Ich werde es versuchen. Thnx. – Tsf