Python async await 不等待
Python async await not waiting
我对异步的工作不多python,但目前我有一个使用 Sanic 框架的项目。有一个 websocket 端点,它从客户端接收数据,向客户端发送消息,该任务已经启动,然后运行长同步任务(没有使其异步的选项),最后向客户端发送消息,任务完成。有一些示例代码:
from sanic import Sanic
from sanic.server.protocols.websocket_protocol import WebSocketProtocol
app = Sanic("TestApp")
@app.websocket("/")
async def process_task(request, ws: WebSocketServerProtocol):
raw_data = await ws.recv()
data = json.loads(raw_data)
await ws.send("TASK STARTED")
process_long_task(data) # Long sync function
await ws.send("TASK ENDED")
但是有个问题。函数不等待 ws.send("TASK STARTED")。实际上这两条消息都是在 process_long_task 完成后才发送的。虽然,如果我在 await ws.send("TASK STARTED")
之后添加 await asyncio.sleep(0.1) 它会正常工作
有人可以指出我的代码有什么问题吗?
如果您从协程调用同步函数,整个循环和其中的所有任务 运行 将等待该同步函数完成。
如果您需要一个长 运行 同步函数,并异步等待结果,有几种方法,大多数人使用某种后台线程。
这是一个异步使用 socket.gethostbyaddr()
(有时完成同步功能非常慢)的示例。
async def GetHostFromAddr(ip):
"""
GetHostFromAddr(ip) -> fqdn\n
:param ip: The hosts ip address ie. 192.168.1.1
:return: Return the fqdn (a string of the form 'sub.example.com') for a host.
"""
loop = asyncio.get_event_loop()
event = asyncio.Event()
pool = ThreadPool(processes=1)
thread_result = pool.apply_async(gethostbyaddr, (ip,), callback=lambda x: loop.call_soon_threadsafe(event.set))
with contextlib.suppress(asyncio.TimeoutError):
if await asyncio.wait_for(event.wait(), 5):
event.clear()
return thread_result.get()[0]
else:
event.clear()
pool.terminate()
我对异步的工作不多python,但目前我有一个使用 Sanic 框架的项目。有一个 websocket 端点,它从客户端接收数据,向客户端发送消息,该任务已经启动,然后运行长同步任务(没有使其异步的选项),最后向客户端发送消息,任务完成。有一些示例代码:
from sanic import Sanic
from sanic.server.protocols.websocket_protocol import WebSocketProtocol
app = Sanic("TestApp")
@app.websocket("/")
async def process_task(request, ws: WebSocketServerProtocol):
raw_data = await ws.recv()
data = json.loads(raw_data)
await ws.send("TASK STARTED")
process_long_task(data) # Long sync function
await ws.send("TASK ENDED")
但是有个问题。函数不等待 ws.send("TASK STARTED")。实际上这两条消息都是在 process_long_task 完成后才发送的。虽然,如果我在 await ws.send("TASK STARTED")
之后添加 await asyncio.sleep(0.1) 它会正常工作有人可以指出我的代码有什么问题吗?
如果您从协程调用同步函数,整个循环和其中的所有任务 运行 将等待该同步函数完成。
如果您需要一个长 运行 同步函数,并异步等待结果,有几种方法,大多数人使用某种后台线程。
这是一个异步使用 socket.gethostbyaddr()
(有时完成同步功能非常慢)的示例。
async def GetHostFromAddr(ip):
"""
GetHostFromAddr(ip) -> fqdn\n
:param ip: The hosts ip address ie. 192.168.1.1
:return: Return the fqdn (a string of the form 'sub.example.com') for a host.
"""
loop = asyncio.get_event_loop()
event = asyncio.Event()
pool = ThreadPool(processes=1)
thread_result = pool.apply_async(gethostbyaddr, (ip,), callback=lambda x: loop.call_soon_threadsafe(event.set))
with contextlib.suppress(asyncio.TimeoutError):
if await asyncio.wait_for(event.wait(), 5):
event.clear()
return thread_result.get()[0]
else:
event.clear()
pool.terminate()