考虑以下代码:
from tornado import ioloop, gen
@gen.coroutine
def test_callback():
print 'entering test_callback'
yield gen.sleep(10)
print 'exiting test_callback'
if __name__ == '__main__':
ioloop.PeriodicCallback(test_callback, 1000 * 5).start()
ioloop.IOLoop.current().start()
这是输出:
entering test_callback
entering test_callback
entering test_callback
exiting test_callback
entering test_callback
exiting test_callback
entering test_callback
...
文档说如果回调需要更长时间,那么将跳过callback_time后续调用。但在这种情况下,这种情况并没有发生。我该怎么做才能确保仅在上一次回调调用完成后调用回调?
答案 0 :(得分:1)
我在thread找到了解决方案。
基本上,如果回调占用更多,那么只有回调是同步的,才会跳过callback_time来执行后续调用。如果回调调用另一个异步例程,则PeriodicCallback无法知道所有将启动另一个回调调用。
在这种情况下,我们需要一个异步感知等效的PeriodicCallback:
from tornado import ioloop, gen
@gen.coroutine
def test_callback():
print 'entering test_callback'
yield gen.sleep(10)
print 'exiting test_callback'
@gen.coroutine
def periodic():
loop = ioloop.IOLoop.current()
while True:
start = loop.time()
yield test_callback()
duration = loop.time() - start
yield gen.Task(loop.add_timeout, max(5 - duration, 0))
if __name__ == '__main__':
ioloop.IOLoop.current().add_callback(periodic)
ioloop.IOLoop.current().start()
这是输出:
entering test_callback
exiting test_callback
entering test_callback
exiting test_callback
entering test_callback
exiting test_callback
...
答案 1 :(得分:0)
也可以使用以下基于python 3.5的解决方案。
from tornado import ioloop, httpclient
class testCls:
def __init__(self):
self.n=0
self.inProcess=False
async def f1(self):
url2='http://yoosofan.github.io/en/'
http_client1 = httpclient.AsyncHTTPClient()
response = await http_client1.fetch(url2)
print('dd: ',self.n)
self.n +=1
async def my_function(self):
print('z',end=' ')
if self.inProcess==False:
self.inProcess=True
await self.f1()
self.inProcess=False
if __name__ == '__main__':
t1=testCls()
ioloop.PeriodicCallback(t1.my_function, 60).start()
ioloop.IOLoop.current().start()