本文以简单易懂的语言来记录关于twisted定时执行某个任务的方法:
1. 如果要让某个程序在 x 秒之后执行,可以用 reactor.callLater() 方法:
# reactor.callLater() 在x秒之后启动f()函数
def f(s):
print("this will run 2 seconds after it was scheduled: %s" % s)
reactor.callLater(2, f, "hello, world")
reactor.run()
2. 如果要接收程序的返回结果和处理异常,可以用 twisted.internet.task.deferLater(clock, delay, *args, callable=None, **kw)
def f(s):
input("inputstr:")
return "This will run 3.5 seconds after it was scheduled: %s" % s
# twisted.internet.task.deferLater(clock, delay, *args, callable=None, **kw)
d = task.deferLater(reactor, 2, f, "hello, world") # 2秒之后触发f()
def call1(pos1):
print(pos1)
d.addCallback(call1) # 加入 call1() 处理函数,等f()延迟结束,会把f()返回的结果通过参数传给call1()
# 打印: This will run 3.5 seconds after it was scheduled: hello, world
def call2(pos1):
print(pos1)
d.addCallback(call1) # 加入 call2()处理函数,等 call1()延迟结束,会把 call1()返回的结果通过参数传给call2(),由于call1()没有返回值,所以这里是打印None
def errcalled(err):
print(err)
d.addErrback(errcalled) # 添加异常处理函数
reactor.run()
3. 如果要让一个循环每隔 x 秒重复一次,可以使用 twisted.internet.task.LoopingCall()
loopTimes = 3
failInTheEnd = False
_loopCounter = 0
def runEverySecond(): # Called at ever loop interval
global _loopCounter
if _loopCounter < loopTimes:
_loopCounter += 1
print('A new second has passed.')
return
if failInTheEnd:
raise Exception('Failure during loop execution.')
# We looped enough times.
loop.stop()
return
def cbLoopDone(result): # Called when loop was stopped with success.
print("Loop done.")
reactor.stop()
def ebLoopFailed(failure): # Called when loop execution failed.
print(failure.getBriefTraceback())
reactor.stop()
loop = task.LoopingCall(runEverySecond)
# Start looping every 1 second.
loopDeferred = loop.start(1.0)
# Add callbacks for stop and failure.
loopDeferred.addCallback(cbLoopDone)
loopDeferred.addErrback(ebLoopFailed)
reactor.run()
本文参考文章:
Scheduling tasks for the future