【发布时间】:2020-03-17 04:55:50
【问题描述】:
我有一个由线程填充的queue.Queue。一个方法尝试从这个队列接收超时。现在假设,另一个线程可以重置我们队列等待的超时,如果队列没有及时送入,我们的接收函数应该继续,更新超时。
我可以按如下方式实现,但是我必须修改内置的queue.Queue 类,以便在等待期间可以修改get() 方法中的endtime 参数...
有没有更好的解决方案? (我不想使用 asyncio...)
from threading import Thread
from queue import Queue, Empty
import time
q = Queue()
TIMEOUT = 1
RESET_TIME = 0.5
PUT_TIME = 1.2
t0 = time.time()
def receive():
try:
_res = q.get(block=True, timeout=TIMEOUT)
print(f'get @ {time.time()-t0}')
return _res
except Empty:
print(f'to @ {time.time()-t0}')
return None
def feed_queue():
time.sleep(PUT_TIME)
print(f'put @ {time.time()-t0}')
q.put_nowait(42)
def reset_timeout():
time.sleep(RESET_TIME)
with q.mutex:
q.endtime += TIMEOUT
print(f'reset @ {time.time()-t0}')
if __name__ == '__main__':
Thread(target=feed_queue).start()
Thread(target=reset_timeout).start()
res = receive()
print('res:', res)
这会产生:
reset @ 0.5013222694396973
put @ 1.201164722442627
get @ 1.201164722442627
res: 42
在 queue.py 中进行了以下修改以使其正常工作:
Index: queue.py
===================================================================
--- queue.py (revision 28725)
+++ queue.py (working copy)
@@ -52,6 +52,7 @@
# drops to zero; thread waiting to join() is notified to resume
self.all_tasks_done = threading.Condition(self.mutex)
self.unfinished_tasks = 0
+ self.endtime = 0
def task_done(self):
'''Indicate that a formerly enqueued task is complete.
@@ -171,9 +172,9 @@
elif timeout < 0:
raise ValueError("'timeout' must be a non-negative number")
else:
- endtime = time() + timeout
+ self.endtime = time() + timeout
while not self._qsize():
- remaining = endtime - time()
+ remaining = self.endtime - time()
if remaining <= 0.0:
raise Empty
self.not_empty.wait(remaining)
【问题讨论】:
标签: python multithreading asynchronous queue timeout