原文出自:Asyncio Event Loops Tutorial
任何基于asyncio的Python程序的主要组件都必须是底层的事件循环。在这个事件循环中,我们可以(来自官方文档):
-
注册,执行和取消调用
-
启动子进程和关联的传输以与外部程序进行通信
-
将代价高昂的函数调用委托给线程池
基本上所有事件循环都是等待事件发生,然后将每个事件匹配到我们已经明确匹配所述事件类型的函数。
一个很好的例子是一个简单的Web服务器,比如说我们的服务器上有一个Web端,它为我们的网站提供了大量不同的页面。我们的事件循环基本上监听请求,然后将这些请求中的每一个与其关联的网页进行匹配。
在上面的示例中对我们的Web服务器发出的每个请求都将被视为一个单独的 event 。然后,这些事件与我们在触发所述事件时预定义的集合函数匹配。
入门:
让我们快速看看如何定义一个非常简单的事件循环。为了实例化一个事件循环,我们将使用asyncio.get_event_loop()
将其包裹在try... finally 我们将指定我们希望新实例化的事件循环运行,直到它完成 myCoroutine() 函数。
import asyncio
# 定义一个想要被执行的协程
async def my_coroutine():
print("my_coroutine")
# 启动快速简单的事件循环并运行直到完成
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(my_coroutine())
finally:
loop.close()
其他运行的参数
我们有许多运行事件循环的选项,我们可以调用run_forever(),然后运行我们的事件循环,直到调用**stop()**函数.
或者我们可以调用 run_until_complete(future) 并且只运行我们的事件循环,直到完成了我们传入的对象
The run_until_complete()方法:
我们快速浏览一下 run_until_complete()函数 ,在这个例子中,我们将定义myWork()协程,然后我们将其传递给run_until_complete函数,然后我们让我们的事件循环运行起来,直到完成 myWork() 协程的执行。
import asyncio
import time
async def my_work():
print("开始执行任务")
time.sleep(5)
print("任务完成")
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(my_work())
finally:
loop.close()
run_forever()方法:
启动事件循环的另一种方法是调用**run_forever()**方法,该方法随后将启动基于asyncio的事件循环,并使其无限期运行,直到程序结束或调用 stop() 方法。应该注意的是,调用它会导致我们的主线程无限期地阻塞。
我们来看一个快速示例,展示这种方法的用法。我们将首先定义我们的 **work()**协程,它将以无限期运行的while循环为特色,并以1秒的间隔打印出 Task 执行完成。
import asyncio
async def work():
while True:
await asyncio.sleep(1)
print("Task 执行完成")
loop = asyncio.get_event_loop()
try:
asyncio.ensure_future(work())
loop.run_forever()
except KeyboardInterrupt:
pass
finally:
print("关闭Loop")
loop.close()
运行多个协程
如果你想无限期地并行运行多个协程,那么你可以通过创建x个协程并让它们分别运行while循环来实现。
然后调用 asyncio.ensure_future(function()) 将其添加在loop, 被加入的协程将在启动loop后无限期的运行。
import asyncio
import time
async def first_worker():
while True:
await asyncio.sleep(1)
print("第一个任务完成")
async def second_worker():
while True:
await asyncio.sleep(1)
print("第二个任务完成")
loop = asyncio.get_event_loop()
try:
asyncio.ensure_future(first_worker())
asyncio.ensure_future(second_worker())
loop.run_forever()
except KeyboardInterrupt:
pass
finally:
print("关闭 Loop")
loop.close()