sched
事件调度器#
sched
模块定义了实现通用事件调度程序的类:
class sched.scheduler(timefunc=time.monotonic, delayfunc=time.sleep)
sched.scheduler
类定义了调度事件的通用接口。它需要两个函数来实际处理“外部世界” ——timefunc
应当不带参数地调用,并返回数字(“时间”,可以为任意单位)。delayfunc
函数应当带参数调用,与timefunc
的输出相兼容,并且应当延迟其所指定的时间单位。每个事件运行后还将调用delayfunc
并传入参数0
以允许其他线程有机会在多线程应用中运行。 在 3.3 版本发生变更:timefunc
和delayfunc
参数是可选的。在 3.3 版本发生变更:
scheduler
类可以安全的在多线程环境中使用。
每个实例通过两个函数进行参数化,timefunc
用于返回当前时间,delayfunc
用于实现延迟。你可以通过替换内置模块 time
中的 time()
和 sleep()
来实现实时调度,或者通过编写自己的函数来实现模拟时间。这也可以用于将调度与 STDWIN 事件集成;延迟函数允许修改队列。时间可以表示为整数或浮点数,只要保持一致即可。
事件由元组 (time, priority, action, argument, kwargs)
指定。就像在 UNIX 中一样,优先级数字越小意味着优先级越高;这样,队列可以维护为优先队列。事件的执行意味着调用 action
函数,向其传递“argument”中的参数序列(记住,在Python中,多个函数参数会被打包成一个序列)和“kwargs”中的关键字参数。
action
函数可能是一个实例方法,因此它有另一种引用私有数据的方式(除了全局变量)。
import sched, time
s = sched.scheduler(time.time, time.sleep)
def print_time(a='default'):
print("From print_time", time.time(), a)
def print_some_times():
print(time.time())
s.enter(10, 1, print_time)
s.enter(5, 2, print_time, argument=('positional',))
# 虽然具有更高的优先级,'keyword' 将在 'positional' 之后运行因为 enter() 是相对的
s.enter(5, 1, print_time, kwargs={'a': 'keyword'})
s.enterabs(1_650_000_000, 10, print_time, argument=("first enterabs",))
s.enterabs(1_650_000_000, 5, print_time, argument=("second enterabs",))
s.run()
print(time.time())
print_some_times()
1731919195.8160007
From print_time 1731919195.816088 second enterabs
From print_time 1731919195.8162458 first enterabs
From print_time 1731919200.8161936 positional
From print_time 1731919200.8165276 keyword
From print_time 1731919205.8161836 default
1731919205.8165004
scheduler.enterabs(time, priority, action, argument=(), kwargs={})
安排新事件。
time
参数应该有数字类型兼容的返回值,与传递给构造函数的timefunc
函数的返回值兼容。计划在相同time
的事件将按其priority
的顺序执行。数字越小表示优先级越高。执行事件意为执行
action(*argument, **kwargs)
。argument
是包含有action
的位置参数的序列。kwargs
是包含action
的关键字参数的字典。返回值是事件,可用于以后取消事件( 参见
cancel()
)。scheduler.enter(delay, priority, action, argument=(), kwargs={})
安排延后
delay
时间单位的事件。除了时间是相对的,其他参数、效果和返回值与enterabs()
相同。scheduler.cancel(event)
从队列中删除事件。如果
event
不是当前队列中的事件,则此方法将引发ValueError
。scheduler.empty()
如果事件队列为空则返回
True
。scheduler.run(blocking=True)
运行所有计划事件。此方法将等待(使用传递给构造器的
delayfunc
函数)进行下一个事件,然后执行它,依此类推直到没有更多的计划事件。如果
blocking
为False
,则执行最快到期(如果有)的预定事件,然后在调度程序中返回下一个预定调用的截止时间(如果有)。action
或delayfunc
都可以引发异常。在任何一种情况下,调度程序都将保持一致状态并传播异常。如果action
引发异常,则在将来调用run()
时不会尝试该事件。如果一系列事件的运行时间大于下一个事件发生前的可用时间,那么调度程序只会保持落后。 没有事件会被丢弃;调用代码负责取消不再相关的事件。
scheduler.queue
只读属性,按照计划运行的顺序返回即将发生的事件列表。 每个事件都显示为 named tuple ,包含以下字段:
time
、priority
、action
、argument
、kwargs
。