Python多进程队列的get方法与sleep的超时比较
我找不到关于Python中队列的get方法带超时的文档:get([block[, timeout]]),而关于Python的time.sleep()却有很好的文档,链接在这里:http://www.pythoncentral.io/pythons-time-sleep-pause-wait-sleep-stop-your-code/。
我用Linux的时间工具测试了一个循环,分别是5、500和5000,时间间隔都是100毫秒,结果看起来差不多。
代码片段1:使用队列超时
while True:
try:
if self._queue.get(True,period) == '!STOP!: break
except:
# Queue.Empty session, keep going
-- do stuff here --
代码片段2:使用时间睡眠
while True:
try:
if self._queue.get_nowait() == '!STOP!: break
except:
# Queue.Empty session, keep going
-- do stuff here --
time.sleep(period)
我更喜欢代码片段1,因为它不是先“睡觉”,然后再检查队列,而是“睡觉”的同时检查队列。当然,这个问题其实不太重要,因为时间间隔通常在0.100到0.500秒之间,但我想确认在queue.get中没有遗漏什么。
1 个回答
1
正如你所说,第一种选择更好,因为它不是无条件地睡眠一段时间(period
),然后检查队列里有没有东西,再继续睡眠。而是你在整个period
期间都在积极等待,有东西被放入队列,这样你就可以在等待'!STOP!'
到来时,偶尔做点其他事情。这里没有什么隐藏的陷阱;get_nowait
内部使用time.time()
加上period
来决定等待多长时间:1)为了能够获取队列的内部锁,2)为了确保队列里确实有东西可以取。以下是来自multprocessing/queues.py
的相关代码:
if block:
deadline = time.time() + timeout
if not self._rlock.acquire(block, timeout): # Waits for up to `timeout` to get the lock
raise Empty # raise empty if it didn't get it
try:
if block:
timeout = deadline - time.time()
if timeout < 0 or not self._poll(timeout): # Once it has the lock, waits for however much time is left before `deadline` to something to arrive
raise Empty
elif not self._poll():
raise Empty
res = self._recv()
self._sem.release()
return res
finally:
self._rlock.release()