asyncio
是 Python 的一个内置库,它的主要用途是编写单线程并发代码,主要通过协程实现。这个库在 Python 3.4 版本中引入,作为 Python 的异步 I/O 框架,提供了基于事件循环的并发模型。
在 Python 3.4 之前,Python 的并发主要依赖于多线程和多进程,但这两种方式都有其局限性。多线程受到全局解释器锁(GIL)的限制,无法充分利用多核 CPU。而多进程虽然可以利用多核 CPU,但进程间的通信复杂,且开销大。因此,Python 社区开始寻找新的并发解决方案,最终在 Python 3.4 中引入了 asyncio
。
asyncio
的主要特点是事件循环和协程。事件循环是 asyncio
的核心,可以理解为一个无限循环,我们可以把一些函数(通过 async
定义的函数,称为协程)注册到事件循环上,当满足事件发生的条件时,调用相应的协程函数。
协程是 asyncio
的另一个重要概念。协程是一种比线程更轻量级的存在,协程的调度完全由用户控制,协程之间的切换不涉及系统调用,开销极小。Python 中的协程并不是线程安全的,它们应该运行在同一个线程中。如果想要在多线程中使用协程,需要为每个线程创建一个事件循环。
Python 3.5 版本对 asyncio
进行了进一步的改进,引入了新的关键字 async
和 await
,使得协程的定义和调用更加简洁明了。
Python 3.7 版本对 asyncio
进行了一些优化和改进,增加了如 asyncio.run()
等新的 API,使得运行和管理协程更加方便。
总的来说,asyncio
的引入使得 Python 在处理 I/O 密集型任务时,能够以更加高效的方式进行并发编程,极大地提高了 Python 的性能。
在 Python 中使用 asyncio
库,首先需要确保你的 Python 环境中已经安装了这个库。如果你的 Python 环境是 3.4 或更高版本,那么 asyncio
库应该已经默认安装。你可以通过以下命令来检查 asyncio
是否已经安装:
import asyncio
如果这个命令没有报错,那么说明 asyncio
已经安装。如果报错,那么你需要通过 pip 来安装 asyncio
库。在命令行中输入以下命令:
pip install asyncio
如果你的 Python 环境是 3.3 或更低版本,那么你需要安装 Trollius 库,这是一个 asyncio
的替代品。你可以通过以下命令来安装 Trollius 库:
pip install trollius
安装完成后,你就可以在 Python 代码中导入 asyncio
库,并使用它的功能了。例如,你可以定义一个异步函数,然后使用 asyncio.run()
来运行这个函数。你也可以使用 asyncio.create_task()
来创建一个任务,然后使用 asyncio.run()
来运行这个任务。
此外,你还可以使用 asyncio
的事件循环功能。事件循环是 asyncio
的核心部分,它可以管理和调度多个异步任务。你可以使用 asyncio.get_event_loop()
来获取当前的事件循环,然后使用事件循环的 run_until_complete()
方法来运行一个任务,或者使用事件循环的 run_forever()
方法来持续运行事件循环。
总的来说,asyncio
库提供了一种简单有效的方式来处理异步 I/O 操作,它可以帮助你编写出更高效的 Python 代码。
在 Python 中,我们可以使用 asyncio
库来实现异步 I/O 操作。这个库使用了协程(coroutine)的概念,使得我们可以在单线程环境中实现并发操作。
首先,我们需要定义一个异步函数,这个函数需要使用 async
关键字进行定义。例如,我们定义一个简单的异步函数 do_something
,这个函数会计算一系列数字的立方并打印出结果:
import asyncio
async def do_something():
l = []
for i in range(10000):
l.append(i ** 3)
print(len(l))
print(\"finish.\")
异步函数需要使用 await
关键字进行调用。如果我们直接调用异步函数,它只会返回一个 coroutine 对象,并不会执行函数。我们需要使用 asyncio.run
来执行异步函数,或者在其他异步函数中使用 await
关键字进行调用:
# 只会返回一个 coroutine 对象,并不会执行函数
def main():
do_something()
# 要用 run 来执行
asyncio.run(do_something())
# 或者在别的异步函数中调用
async def main():
await do_something() # 异步函数通过 await 来调用,await 只能放在 async 函数内
asyncio.run(main())
我们也可以通过旧式的 API 运行异步函数:
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
如果我们需要同时执行多个异步函数,我们需要将异步函数定义为 task。我们可以使用 asyncio.create_task
来创建 task,然后使用 await
关键字来启动所有的 task:
async def main():
print(f\"started at {time.strftime('%X')}\")
task1 = asyncio.create_task(do_something_cost_time(\"WashClothes\", 2))
task2 = asyncio.create_task(do_something_cost_time(\"WatchTV\", 5))
task3 = asyncio.create_task(do_something_cost_time(\"FeedBaby\", 3))
await task1
await task2
await task3
print(f\"finished at {time.strftime('%X')}\")
asyncio.run(main())
我们也可以使用 asyncio.gather
的方式同时定义并执行 tasks:
async def main():
await asyncio.gather(
do_something_cost_time(\"WashClothes\", 2),
do_something_cost_time(\"WatchTV\", 5),
do_something_cost_time(\"FeedBaby\", 3),
)
asyncio.run(main())
或者通过旧式的 API 运行:
loop = asyncio.get_event_loop()
tasks = [
do_something_cost_time(\"WashClothes\", 2),
do_something_cost_time(\"WatchTV\", 5),
do_something_cost_time(\"FeedBaby\", 3),
]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
在 asyncio
中,事件循环(Event Loop)是非常重要的一个概念。事件循环的核心是一个 Queue,在一个循环中不断 pop 下一个 ready 的 callback 来执行。我们可以使用以下方式来创建和操作事件循环:
# create and access a new asyncio event loop
loop = asyncio.new_event_loop()
# access the running event loop
loop = asyncio.get_running_loop()
# to execute a task (blocking)
loop.run_until_complete(asyncio.sleep(2))
# schedule a task (non blocking)
task = loop.create_task(asyncio.sleep(2))
# close the event loop
loop.close()
# stop the event loop
loop.stop()
# run forever until stopped
loop.run_forever()
# check loop status
loop.is_running()
loop.is_closed()
我们也可以在 Process/Thread Executor 中运行事件循环:
# create an executor
with ThreadPoolExecutor() as exe:
# execute a function in event loop using executor
loop.run_in_executor(exe, task)
以上就是 Python 中 asyncio
库的基本使用方法,希望对你有所帮助。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。