
import logging; logging.basicConfig(level=logging.INFO) import asyncio, os, json, time from datetime import datetime from aiohttp import web def index(request): logging.info('server response...') return web.Response(body=b'<h1>Awesome</h1>') async def init(loop): app = web.Application(loop=loop) app.router.add_route('GET', '/', index) logging.info('server before...') srv = await loop.create_server(app.make_handler(), '127.0.0.1', 9000) logging.info('server started at http://127.0.0.1:9000...') return srv loop = asyncio.get_event_loop() loop.run_until_complete(init(loop)) loop.run_forever() 我觉得运行的日志:
INFO:root:server before... INFO:root:server response... INFO:root:server started at http://127.0.0.1:9000... 结果正确的日志是:
INFO:root:server before... INFO:root:server started at http://127.0.0.1:9000... INFO:root:server response... 在我的理解里, python 执行到 await 应该暂停执行函数, TCP 协程结束后,才执行 server started at...这条日志。怎么函数一下子全部执行完了。
1 cloverstd 2016 年 11 月 3 日 via iPhone 因为你的 init 函数没有用 await init 调用 |
2 ifaii 2016 年 11 月 3 日 async def init(loop): 学艺不精 看不懂-_-|| |
3 nicegoing OP @cloverstd https://docs.python.org/3/library/asyncio-task.html#example-chain-coroutines 这是 python 的官方示例。这个例子调用的时候也没有 await 调用呀 ``` import asyncio async def compute(x, y): print("Compute %s + %s ..." % (x, y)) await asyncio.sleep(1.0) return x + y async def print_sum(x, y): result = await compute(x, y) print("%s + %s = %s" % (x, y, result)) loop = asyncio.get_event_loop() loop.run_until_complete(print_sum(1, 2)) loop.close() ``` |
4 sujin190 2016 年 11 月 3 日 没错啊, create_server 只是 bing 了没有 listen 啊,所以立刻返回了, run_forever 才进行 listen 的行为 |
6 sujin190 2016 年 11 月 3 日 没错啊, create_server 只是 bind 了没有 listen 啊,所以立刻返回了, run_forever 才进行 listen 的行为 |
8 ruoyu0088 2016 年 11 月 3 日 loop.create_server 是创建一个服务器对象, await loop.create_server(...)是等待创建这个服务器对象,并不是等待这个服务器响应请求。 |
9 yufpga 2016 年 11 月 3 日 await 的语义相当于 yield from(首先你得先搞清楚这个东西), 不要和 yield 这个鬼搞混淆了, 出现 async 和 await 支持的原因本就是为了使用写同步代码的方式写出异步的效果.在你这里, 正常逻辑考虑, 你的 server 都还没有创建, 怎么可能请求成功, 从而执行 index 函数.建议 debug 追踪下代码内部的执行逻辑,要熟悉其内部原理, 最好看一下 asyncio 的源码, 自己实现一下 |
12 yufpga 2016 年 11 月 3 日 @sujin190 你的说法是有问题的, run_forever 并不是进行 server 的 listen 的行为,而是执行了一段类似与下面的代码 while not self.stopped: events = selector.select(self.select_timeout) if not events: raise Exception('轮询超时') for event_key, event_mask in events: callback = event_key.data callback(event_key, event_mask) 用来取出可读可写等事件, 其实就是通过事件循环驱动(通知)阻塞程序恢复执行 |
14 lytofb 2016 年 11 月 3 日 没什么问题啊, win7 64 位 python 3.5.2 |