daw*_*an6 5 python asynchronous nonblocking built-in python-3.x
我想了解如何blocking在方法中使用可选参数scheduler.run(blocking=True)。任何实际的/实际的示例都将非常有帮助。
根据我到目前为止所做的研究,blocking可选参数的意图是用于非阻塞或异步应用程序[1] [2]。以下是schduler的主要运行循环(来自python 3.6库sched.py)。在执行该代码之后,我注意到,只要blocking将设置为False,就立即返回目标时间与当前时间之间的时差,除非目标时间过去了,在这种情况下将执行该操作。
while True:
with lock:
if not q:
break
time, priority, action, argument, kwargs = q[0]
now = timefunc()
if time > now:
delay = True
else:
delay = False
pop(q)
if delay:
if not blocking:
return time - now
delayfunc(time - now)
else:
action(*argument, **kwargs)
delayfunc(0) # Let other threads run
Run Code Online (Sandbox Code Playgroud)
在我看来,非阻塞设计要求我继续运行调度程序,直到队列干净为止。因此,我正在考虑自己维护任务队列,并继续将scheduler.run任务推入队列(如下面的代码。)这是否是理想的设计?使用非阻塞调度程序的正确方法是什么?
def action():
print('action at: ', datetime.now())
if __name__ == '__main__':
s = sched.scheduler(time.time)
target_time = datetime.now() + timedelta(seconds=5)
s.enterabs(target_time.timestamp(), 1, action)
run = functools.partial(s.run, blocking=False)
taskq = deque()
taskq.append(run)
while taskq:
task = taskq.popleft()
result = task()
print(result)
if result:
taskq.append(run)
time.sleep(1)
print('end tasks')
Run Code Online (Sandbox Code Playgroud)
[1] Python 3.3的新增功能
老问题,但我刚刚实现了一些非常有效地使用非阻塞版本的东西。
当blocking = Truein 时sched.scheduler.run,它将调用delayfunc计算时间差,直到下一个事件。
如果您的应用程序 at为t = 0安排一个事件,但另一个线程 at为安排一个事件,则这可能是不可取的。在这种情况下,At = 10t = 1Bt = 5
s = sched.scheduler(time.time)
# Spawn threads which enter A and B into s
while True:
s.run(True)
Run Code Online (Sandbox Code Playgroud)
如果你的主线程只是sched.scheduler.run(blocking=True)在循环中调用, att = 0它将调用,delayfunc(10)因为它只看到它还剩下 10 个时间单位,直到A。主线程直到 t = 10 才会醒来,此时它会发现它错过了B,延迟运行B5 个时间单位,然后A在 后运行B。
要解决这个问题,您可以将主线程更改为如下所示:
s = sched.scheduler(time.time)
# Spawn threads which enter A and B into s
while True:
next_ev = s.run(False)
if next_ev is not None:
time.sleep(min(1, next_ev))
else:
time.sleep(1)
Run Code Online (Sandbox Code Playgroud)
此代码将赶上所有当前事件,然后休眠直到下一个事件,或者如果没有下一个事件或下一个事件太早,将休眠 1 秒。
理想情况下,调度程序将使用条件变量来实现,如果新事件到达优先级队列的前面,则调度程序可以等待该变量,而不只是休眠直到下一个事件。这将是最有效且最准确的。