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
Run Code Online (Sandbox Code Playgroud)
需要注意的事项:
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.')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14481 次 |
| 最近记录: |