Nik*_* B. 22 python multithreading synchronization
有没有办法在Python中为多线程目的实现锁定,其acquire方法可以有任意超时?到目前为止,我发现的唯一可行的解决方案是使用轮询
有没有更好的方法来实现这个?
Sin*_*ion 21
详细阐述史蒂文的评论建议:
import threading
import time
lock = threading.Lock()
cond = threading.Condition(threading.Lock())
def waitLock(timeout):
    with cond:
        current_time = start_time = time.time()
        while current_time < start_time + timeout:
            if lock.acquire(False):
                return True
            else:
                cond.wait(timeout - current_time + start_time)
                current_time = time.time()
    return False
需要注意的事项:
threading.Lock()对象,一个是内部的threading.Condition().  cond,获得锁定; 该wait()操作进行解锁,虽然如此,任意数量的线程可以看它.threading.Condition可以通过超时以外的原因获得通知,因此您仍需要跟踪时间,如果您确实希望它过期.waitLock函数的调用者应该跟a一个lock.release()a,cond.notify()以便等待它的其他线程被通知他们应该重试获取锁.这未在示例中显示.我的版本使用线程安全队列http://docs.python.org/2/library/queue.html及其支持超时的put/get方法.
到目前为止工作正常,但如果有人可以对其进行同行评审,我将不胜感激.
"""
Thread-safe lock mechanism with timeout support module.
"""
from threading import ThreadError, current_thread
from Queue import Queue, Full, Empty
class TimeoutLock(object):
    """
    Thread-safe lock mechanism with timeout support.
    """
    def __init__(self, mutex=True):
        """
        Constructor.
        Mutex parameter specifies if the lock should behave like a Mutex, and
        thus use the concept of thread ownership.
        """
        self._queue = Queue(maxsize=1)
        self._owner = None
        self._mutex = mutex
    def acquire(self, timeout=0):
        """
        Acquire the lock.
        Returns True if the lock was succesfully acquired, False otherwise.
        Timeout:
        - < 0 : Wait forever.
        -   0 : No wait.
        - > 0 : Wait x seconds.
        """
        th = current_thread()
        try:
            self._queue.put(
                th, block=(timeout != 0),
                timeout=(None if timeout < 0 else timeout)
            )
        except Full:
            return False
        self._owner = th
        return True
    def release(self):
        """
        Release the lock.
        If the lock is configured as a Mutex, only the owner thread can release
        the lock. If another thread attempts to release the lock a
        ThreadException is raised.
        """
        th = current_thread()
        if self._mutex and th != self._owner:
            raise ThreadError('This lock isn\'t owned by this thread.')
        self._owner = None
        try:
            self._queue.get(False)
            return True
        except Empty:
            raise ThreadError('This lock was released already.')