我有以下基于Python的Tornado编写的代码:
def process_data(data):
# To something
def handler(message):
if message['type'] == 'message':
data = message['data']
IOLoop.current().spawn_callback(process_data, data)
async def main():
redis_client = RedisClient(redis_conf)
pubsub = redis_client.subscribe("CHANNEL", handler)
async def fetch_messages():
while True:
pubsub.get_message()
await gen.sleep(0.0001)
await fetch_messages()
if __name__ == "__main__":
import logging
logging.basicConfig()
parse_command_line()
tornado.web.Application(debug=options.debug)
io_loop = ioloop.IOLoop.current()
io_loop.run_sync(main)
鉴于上面的代码,我可以看到正在调用process_data
。但是,如果我删除等待gen.sleep(0.0001)
,则永远不会调用process_data
。有谁知道为什么?
答案 0 :(得分:2)
IOLoop.spawn_callback(回调,* args,** kwargs)
在下一次IOLoop迭代上调用给定的回调。
如果你一直在调用一些同步代码(while True
没有await
),你就不会将控制权返回给事件循环,而事件循环也无法让迭代执行回调。
行await gen.sleep(0.0001)
- 是控件返回事件循环的地方,因此它可以执行某些操作(如执行回调)。
Tornado有特殊的对象可以将控制权返回到事件循环中,例如你的{ - 3}}:
while True:
pubsub.get_message()
await gen.moment
我没有使用Tornado,但我敢打赌,更好的方法是使用一些专为异步程序设计的redis客户端gen.moment。