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-03 09:08:05 +08:00 via iPhone
因为你的 init 函数没有用 await init 调用
|
2
ifaii 2016-11-03 09:11:30 +08:00
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-03 09:20:45 +08:00
没错啊, create_server 只是 bing 了没有 listen 啊,所以立刻返回了, run_forever 才进行 listen 的行为
|
6
sujin190 2016-11-03 09:21:58 +08:00
没错啊, create_server 只是 bind 了没有 listen 啊,所以立刻返回了, run_forever 才进行 listen 的行为
|
8
ruoyu0088 2016-11-03 09:30:55 +08:00
loop.create_server 是创建一个服务器对象, await loop.create_server(...)是等待创建这个服务器对象,并不是等待这个服务器响应请求。
|
9
yufpga 2016-11-03 09:36:57 +08:00
await 的语义相当于 yield from(首先你得先搞清楚这个东西), 不要和 yield 这个鬼搞混淆了, 出现 async 和 await 支持的原因本就是为了使用写同步代码的方式写出异步的效果.在你这里, 正常逻辑考虑, 你的 server 都还没有创建, 怎么可能请求成功, 从而执行 index 函数.建议 debug 追踪下代码内部的执行逻辑,要熟悉其内部原理, 最好看一下 asyncio 的源码, 自己实现一下
|
12
yufpga 2016-11-03 09:57:13 +08:00
@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-03 11:03:45 +08:00
没什么问题啊, win7 64 位 python 3.5.2
|