我的代码需要gen.sleep来执行函数异步?

时间:2017-07-20 20:46:47

标签: python asynchronous tornado python-asyncio tornado-redis

我有以下基于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。有谁知道为什么?

1 个答案:

答案 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