基本介绍
# Event source / Event loop /Event handler await
Event Loop callbacks
awaitable对象: Coroutines Tasks Futures
语法: async/await
相关概念 阻塞Blocking IO-bound
#The event loop is the core of every asyncio application.
Event loops run asynchronous tasks and callbacks, perform network IO operations, and run subprocesses.
# 协程 任务 future 回调函数
# 状态 挂起 执行 阻塞
# 协程函数: 定义形式为 async def 的函数
API
Low-level API 低层级 API 以支持 库和框架的开发
Event Loop Methods: loop.run_until_complete loop.call_soon
High-level API
create_task() Start an asyncio Task.
run() Create event loop, run a coroutine, close the loop.
await gather() Schedule and wait for things concurrently.
await wait() Monitor for completion.
# asyncio.ensure_future(coroutine) 和 loop.create_task(coroutine)都可以创建一个task
#CPU- (计算密集型) 和 I/O bound(I/O密集型)
代码示例
#!/usr/bin/env python3
import time
import asyncio
# awaitable objects: coroutines, Tasks, and Futures.
async def do_some_work(x):
print('Waiting: ', x)
def callback(future):
print('Callback: ', future.result())
if __name__ == "__main__":
now = lambda : time.time()
start = now()
coroutine_01 = do_some_work(2)
loop = asyncio.get_event_loop()
loop.run_until_complete(coroutine_01)
print('TIME01 : ', now() - start)
# asyncio.ensure_future(coroutine) 和 loop.create_task(coroutine)都可以创建一个task
coroutine1 = do_some_work(3)
loop = asyncio.get_event_loop()
# task = asyncio.ensure_future(coroutine)
task = loop.create_task(coroutine1)
print("M1: ", task)
loop.run_until_complete(task)
print("M2: ", task)
print('TIME: ', now() - start)
# task是Future的子类
print(isinstance(task, asyncio.Future))
coroutine2 = do_some_work(4)
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(coroutine2)
task.add_done_callback(callback)
loop.run_until_complete(task)
print('TIME: ', now() - start)
# 协程遇到await,事件循环将会挂起该协程,执行别的协程,直到其他的协程也挂起或者执行完毕,再进行下一个协程的执行
# 一群task任务
# asyncio.wait(tasks) 也可以使用 asyncio.gather(*tasks) ,前者接受一个task列表,后者接收一堆task
# syncio.gather创建协程对象,那么await的返回值就是协程运行的结果。
coroutine5 = do_some_work(5)
coroutine6 = do_some_work(6)
tasks = [
asyncio.ensure_future(coroutine5),
asyncio.ensure_future(coroutine6)
] # 将协程作为参数创建任务
loop = asyncio.get_event_loop() # 创建事件循环
loop.run_until_complete(asyncio.wait(tasks)) # 运行协程
# 打印协程返回值,注意只有协程结束后才可获得返回值
print("返回值:", tasks[0].result())
print("返回值:", tasks[0].result())
# Pending Running Done Cancelled
# 有一种方式实现这种类似master-worker的方案
# 主线程用于监听队列,然后子线程的做事件循环的worker是一种方式。
# To actually run a coroutine, asyncio provides three main mechanisms
# 01. asyncio.run() function
# 02. asyncio.create_task() function to run coroutines concurrently as asyncio Tasks.
# Low low-level
#high
# asyncio.StreamReader asyncio.StreamWrite asyncio.open_connection asyncio.open_unix_connection asyncio.start_unix_server
# asyncio.create_subprocess_exec asyncio.subprocess.PIPE asyncio.create_subprocess_shell asyncio.subprocess.STDOUT
# asyncio.Queue asyncio.PriorityQueue asyncio.LifoQueue
# asyncio.Lock asyncio.Event asyncio.Condition asyncio.Semaphore asyncio.BoundedSemaphore
网络编程
Concurrency is about dealing with lots of things at once.
Parallelism is about doing lots of things at once.
Not the same, but related.
One is about structure, one is about execution.
Concurrency provides a way to structure a solution to solve a problem that may (but not
necessarily) be parallelizable.
———— Rob Pike (Co-inventor of the Go language)
网络编程里-阻塞IO、非阻塞IO、同步IO、异步IO等概念
进程的阻塞是进程自身的一种主动行为,也因此只有处于运行态的进程(获得CPU),才可能将其转为阻塞状态
事件驱动编程是一种网络编程范式
I/O多路复用的本质就是用select/poll/epoll,去监听多个socket对象,
如果其中的socket对象有变化,只要有变化,用户进程就知道了。
select是不断轮询去监听的socket,socket个数有限制,一般为1024个;
selectors
poll还是采用轮询方式监听,只不过没有个数限制;
epoll并不是采用轮询方式去监听了,而是当socket有变化时通过回调的方式主动告知用户进程
功能与linux的epoll,还是select模块,poll等类似;实现高效的I/O multiplexing, 常用于非阻塞的socket的编程中