【发布时间】:2021-09-24 01:27:09
【问题描述】:
我正在尝试实现一个同步端点,将作业排入队列,等待作业完成,然后返回结果。
lock = Condition()
def predicate(job_in_queue):
job_in_queue.refresh()
print(job_in_queue.get_status())
print(datetime.datetime.now())
if job_in_queue.get_status() == "finished":
return True
return False
print(datetime.datetime.now())
with lock:
if lock.wait_for(lambda: predicate(job), timeout=10):
print("indeed notified")
else:
print("failed to notify")
print(datetime.datetime.now())
print(datetime.datetime.now())
return job.result
python条件变量wait_for方法wait_for(predicate, timeout=None),会停在这一行,等到callable传入predicate,返回True,然后继续后面的代码。参考the documentation。
但是,根据我的打印行,predicate 似乎没有被经常检查。它只在第一次传入/第一次调用wait_for 时检查一次,然后它统计空闲并且只在t=timeout 秒后检查它第二次,其中timeout 是我通过的数字在我的打印行中,它仅在 10 秒后检查 predicate(我在上面的代码中指定的 timeout 值)。
2021-07-15T13:48:33.98+0800 [APP/PROC/WEB/0] OUT 2021-07-15 05:48:23.954320
2021-07-15T13:48:33.98+0800 [APP/PROC/WEB/0] OUT queued
2021-07-15T13:48:33.98+0800 [APP/PROC/WEB/0] OUT 2021-07-15 05:48:23.974196
2021-07-15T13:48:33.98+0800 [APP/PROC/WEB/0] OUT finished
2021-07-15T13:48:33.98+0800 [APP/PROC/WEB/0] OUT 2021-07-15 05:48:33.986337
2021-07-15T13:48:33.98+0800 [APP/PROC/WEB/0] OUT indeed notified
2021-07-15T13:48:33.98+0800 [APP/PROC/WEB/0] OUT 2021-07-15 05:48:33.987215
2021-07-15T13:48:33.98+0800 [APP/PROC/WEB/0] OUT 2021-07-15 05:48:33.987233
我进一步验证了这个问题确实是 predicate 没有通过将 timeout 更改为 15 来不断检查,并且它再次仅在 15 秒后检查 predicate 的结果。
有没有办法让predicate 不断检查这里?不是while True 忙等待,因为它会占用 CPU(并且永远不会通过代码审查)。或者threading.Condition.wait_for 是正确的方式吗?
【问题讨论】:
标签: python multithreading locking wait task-queue