我已经看过几个关于asyncio的基本Python 3.5教程,它们以各种方式执行相同的操作.在这段代码中:
import asyncio
async def doit(i):
print("Start %d" % i)
await asyncio.sleep(3)
print("End %d" % i)
return i
if __name__ == '__main__':
loop = asyncio.get_event_loop()
#futures = [asyncio.ensure_future(doit(i), loop=loop) for i in range(10)]
#futures = [loop.create_task(doit(i)) for i in range(10)]
futures = [doit(i) for i in range(10)]
result = loop.run_until_complete(asyncio.gather(*futures))
print(result)
Run Code Online (Sandbox Code Playgroud)
上面定义futures变量的所有三个变体都实现了相同的结果; 我能看到的唯一区别是,对于第三个变体,执行是乱序的(在大多数情况下这应该无关紧要).还有其他区别吗?有些情况下我不能只使用最简单的变体(协程的简单列表)吗?
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time
async def foo():
await time.sleep(1)
foo()
Run Code Online (Sandbox Code Playgroud)
我无法使这个简单的例子运行:
RuntimeWarning: coroutine 'foo' was never awaited foo()
Run Code Online (Sandbox Code Playgroud) 我正在迁移tornado到asyncio,而且我找不到asyncio相同tornado的东西PeriodicCallback.(A PeriodicCallback有两个参数:运行的函数和调用之间的毫秒数.)
asyncio?RecursionError一会儿的风险?我有以下代码:
@asyncio.coroutine
def do_something_periodically():
while True:
asyncio.async(my_expensive_operation())
yield from asyncio.sleep(my_interval)
if shutdown_flag_is_set:
print("Shutting down")
break
Run Code Online (Sandbox Code Playgroud)
我运行此功能直到完成.设置关闭时会出现问题 - 该功能完成,任何挂起的任务都不会运行.(你认为这是一个错误
task: <Task pending coro=<report() running at script.py:33> wait_for=<Future pending cb=[Task._wakeup()]>>
Run Code Online (Sandbox Code Playgroud)
).如何正确安排关机?
为了给出一些上下文,我正在编写一个系统监视器,它每隔5秒从/ proc/stat读取一次,计算该时间段内的CPU使用率,然后将结果发送到服务器.我想继续安排这些监视作业,直到我收到sigterm,当我停止调度,等待所有当前作业完成,然后正常退出.
从谁写ASYNCIO代码,但正在寻求更好地理解内部工作的人的角度来看,是什么yield from,await以及如何允许异步代码这些有用吗?
有一个高度赞成的问题询问yield from语法的用法和解释异步和等待的问题,但两者都深入讨论了不同的主题,并不是对底层代码及其如何适应asyncio的简明解释.
我在Python 3.5+中读过许多关于asyncio/ async/的博客文章,问题/答案await,很多都是复杂的,我发现最简单的可能是这个.它仍然使用ensure_future,并且为了学习Python中的异步编程,我想看看是否有更简单的例子是可能的(即,执行基本异步/等待示例所需的最小工具是什么).
问题:为了学习Python中的异步编程,是否可以通过仅使用这两个关键字+ + +其他Python代码但没有其他函数来提供一个显示如何async/ await工作的简单示例?asyncio.get_event_loop()run_until_completeasyncio
示例:类似这样的事情:
import asyncio
async def async_foo():
print("async_foo started")
await asyncio.sleep(5)
print("async_foo done")
async def main():
asyncio.ensure_future(async_foo()) # fire and forget async_foo()
print('Do some actions 1')
await asyncio.sleep(5)
print('Do some actions 2')
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud)
但没有ensure_future,仍然演示了await/async的工作原理.
我目前在关闭应用程序的CTRL-C期间关闭asyncio协同程序时遇到问题.以下代码是我现在所拥有的精简版:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import asyncio
import time
import functools
import signal
class DummyProtocol(asyncio.Protocol):
def __init__(self, *args, **kwargs):
self._shutdown = asyncio.Event()
self._response = asyncio.Queue(maxsize=1)
super().__init__(*args, **kwargs)
def connection_made(self, transport):
self.transport = transport
def close(self):
print("Closing protocol")
self._shutdown.set()
def data_received(self, data):
#data = b'OK MPD '
# Start listening for commands after a successful handshake
if data.startswith(b'OK MPD '):
print("Ready for sending commands")
self._proxy_task = asyncio.ensure_future(self._send_commands())
return
# saving response for later consumption in self._send_commands
self._response.put_nowait(data)
async …Run Code Online (Sandbox Code Playgroud) 假设我有一个像这样的异步生成器:
async def event_publisher(connection, queue):
while True:
if not await connection.is_disconnected():
event = await queue.get()
yield event
else:
return
Run Code Online (Sandbox Code Playgroud)
我是这样消费的:
published_events = event_publisher(connection, queue)
async for event in published_events:
# do event processing here
Run Code Online (Sandbox Code Playgroud)
它工作得很好,但是当连接断开并且没有发布新事件时,async for它将永远等待,所以理想情况下,我想像这样强行关闭生成器:
if connection.is_disconnected():
await published_events.aclose()
Run Code Online (Sandbox Code Playgroud)
但我收到以下错误:
RuntimeError: aclose(): asynchronous generator is already running
有没有办法停止处理已经运行的发电机?
我试图了解如何在aioweb框架内从coroutine处理程序运行异步进程.这是一个代码示例:
def process(request):
# this function can do some calc based on given request
# e.g. fetch/process some data and store it in DB
# but http handler don't need to wait for its completion
async def handle(request):
# process request
process(request) ### THIS SHOULD RUN ASYNCHRONOUSLY
# create response
response_data = {'status': 'ok'}
# Build JSON response
body = json.dumps(response_data).encode('utf-8')
return web.Response(body=body, content_type="application/json")
def main():
loop = asyncio.get_event_loop()
app = web.Application(loop=loop)
app.router.add_route('GET', '/', handle)
server = loop.create_server(app.make_handler(), '127.0.0.1', 8000) …Run Code Online (Sandbox Code Playgroud) 我有一个长时间运行的同步 Python 程序,我希望每秒运行大约 10 个“即发即忘”任务。这些任务调用远程 API,不需要返回任何值。我尝试了这个答案,但它需要太多的CPU/内存来生成和维护所有单独的线程,所以我一直在研究asyncio。
这个答案很好地解释了如何使用 asyncio 运行“即发即忘”。但是,它需要使用 using run_until_complete(),它会等待所有异步任务完成。我的程序使用同步 Python,所以这对我不起作用。理想情况下,代码应该像这样简单,log_remote不会阻塞循环:
while True:
latest_state, metrics = expensive_function(latest_state)
log_remote(metrics) # <-- this should be run as "fire and forget"
Run Code Online (Sandbox Code Playgroud)
我使用的是Python 3.7。如何在另一个线程上使用 asyncio 轻松运行它?
python ×10
python-3.x ×4
async-await ×3
coroutine ×3
python-3.5 ×3
asynchronous ×2
generator ×2
aiohttp ×1
python-3.4 ×1
tornado ×1