asyncio.run
,
asyncio.run_coroutine_threadsafe
,
loop.run_until_complete
, 和
create_task
是 Python asyncio 中用于管理协程的不同方法,它们在协程的执行和管理方式上有一些区别。
-
asyncio.run
:
-
asyncio.run
是 Python 3.7+ 引入的,用于运行一个协程并等待其完成。
-
它通常用于应用程序的主入口点,以便在应用程序中方便地运行一个协程。
-
它创建一个新的事件循环,运行协程,等待协程完成,然后关闭事件循环。
示例:
import asyncio
async def main():
await asyncio.sleep(1)
print("Hello, world!")
asyncio.run(main())
-
asyncio.run_coroutine_threadsafe
:
-
asyncio.run_coroutine_threadsafe
是用于在一个线程中安全地运行协程,并且可以从另一个线程提交协程进行执行。
-
这在多线程环境下是有用的,可以安全地将协程任务提交给事件循环。
-
它返回一个 concurrent.futures.Future 对象,您可以使用
.result()
方法来等待协程的结果。
-
asyncio.run_coroutine_threadsafe
函数通常在多线程环境中使用,它会将协程提交到指定的事件循环(在本例中是
loop
)中运行,并返回一个
concurrent.futures.Future
对象。在代码中,使用
future.result()
获取协程的结果,但可能因为线程同步的问题导致卡死。
如果你在单线程环境中使用 asyncio,最简单的方式是使用
asyncio.run
来运行协程
示例:
import asyncio
async def my_coroutine():
await asyncio.sleep(1)
return "Hello, world!"
async def main():
future = asyncio.create_task(my_coroutine())
result = await future
return result
if __name__ == "__main__":
result = asyncio.run(main())
print(result)
-
loop.run_until_complete
:
-
loop.run_until_complete
是 asyncio 事件循环对象的方法,用于运行一个协程并等待其完成。
-
这个方法只能在事件循环的上下文中使用。
-
它会一直阻塞,直到协程执行完成,然后返回协程的结果。
示例:
import asyncio
async def my_coroutine():
await asyncio.sleep(1)
return "Hello, world!"
loop = asyncio.get_event_loop()
result = loop.run_until_complete(my_coroutine())
print(result)
-
create_task
:
-
create_task
是 asyncio 事件循环对象的方法,用于将协程封装为一个任务对象并立即返回任务对象。
-
任务是协程的包装器,它可以在后台并行执行,而不需要等待其完成。
-
通常用于同时启动多个协程任务。
示例:
import asyncio
async def my_coroutine(task_name, seconds):
await asyncio.sleep(seconds)
return f"{task_name} completed after {seconds} seconds"
async def main():
task1 = asyncio.create_task(my_coroutine("Task 1", 2))
task2 = asyncio.create_task(my_coroutine("Task 2", 1))
# 此处可以做其他事情,不需要等待任务完成
result1 = await task1
result2 = await task2
print(result1)
print(result2)
asyncio.run(main())
asyncio.run
用于运行一个协程并等待其完成,通常在应用程序的入口点处使用。asyncio.run_coroutine_threadsafe
用于在多线程环境中安全地运行协程,可以从不同的线程中提交协程进行执行。loop.run_until_complete
用于运行一个协程并等待其完成,通常在事件循环的上下文中使用。create_task
用于创建并行执行的任务,通常在需要同时启动多个协程时使用,然后您可以等待这些任务的完成。
协程,又称微线程,纤程,也称为用户级线程,在不开辟线程的基础上完成多任务,也就是在单线程的情况下完成多任务,多个任务按照一定顺序交替执行 通俗理解只要在def里面只看到一个yield关键字表示就是协程。
协程是也是实现多任务的一种方式。asyncio模块的使用。
基于async & await关键字的协程可以实现异步编程,这也是目前python异步相关的主流技术。
1.事件循环
可以理解成为一个死循环,去检查任务列表中的任务,如果可执行就去执行,如果检查不到就是不可执行的,那就忽略掉去执行其他可执行的任务,如果IO结束了(比如说去百度下载图片,下载完了就会变成可执行任务)再去执行下载完成之后的逻辑
#这里的任务是有状态的,比如这个任务已经完成或者正在执行或者正在IO等待
任务列表 = [ 任务1, 任务2, 任务3,... ]
while True
计算型的操作,利用协程来回切换执行,没有任何意义,来回切换并保存状态反倒会降低性能。
IO型的操作,利用协程在IO等待时间就去切换执行其他任务,当IO操作结束后再自动回调,那么就会大大节省资源并提供性能,从而实现异步编程(不等待任务结束就可以去执行其他代码)
2. 协程和多线程之间的共同点和区别:
都是并发操作,多线程同一时间点只能有一个线程在执行,协程同一时间点只能有一个任务在执行;
多线程,是在I/O阻塞时通过...
协程(Coroutine),也可以被称为微线程,是一种用户态内的上下文切换技术。简而言之,其实就是通过一个线程实现代码块相互切换执行
在Python中有多种方式可以实现协程,例如:
greenlet,是一个第三方模块,用于实现协程代码(Gevent协程就是基于greenlet实现)
yield,生成器,借助生成器的特点也可以实现协程代码。
asyncio,在Python3.4中引入的模块用于编写协程代码。
async & awiat,在Python3.5中引入的两个关键字,结合as
`asyncio.get_event_loop().run_until_complete` 是 Python asyncio 库中的另一个函数,它也可以运行一个协程直到完成,但与 `asyncio.run_until_complete` 不同的是,它需要先获取一个事件循环对象,然后在这个事件循环对象上运行协程。这个函数通常用于在一个事件循环中运行多个协程任务。
下面是一个使用 `asyncio.get_event_loop().run_until_complete` 运行协程的示例:
import asyncio
async def my_coroutine():
await asyncio.sleep(1)
return "Hello, World!"
loop = asyncio.get_event_loop()
result = loop.run_until_complete(my_coroutine())
print(result)
在上面的示例中,我们首先获取一个事件循环对象 `loop`,然后使用 `loop.run_until_complete` 运行协程。这个函数会在 `loop` 上运行协程,直到协程运行结束才会返回结果。和 `asyncio.run_until_complete` 一样,这个函数也是阻塞的,直到协程运行结束才会返回结果。
需要注意的是,每个线程只能有一个事件循环对象,因此如果你在一个线程中使用 `asyncio.get_event_loop().run_until_complete` 运行协程,那么在这个线程中就不能再使用其他的事件循环对象了。如果你需要在同一个线程中运行多个协程任务,那么应该使用同一个事件循环对象。