Python编程——异步IO

异步IO:当代码需要执行一个耗时的IO操作时,它只发出IO指令,并不等待IO结果,然后就去执行其他代码

同步IO:遇到IO操作,如读写文件、发送网络数据时,需要等待IO操作完成

协程

单线程实现并发,在应用程序里控制多个任务的切换+保存状态,有线程切换的开销,使用yield

协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的

https://www.liaoxuefeng.com/wiki/1016959663602400/1017959540289152

使用的原因:不能无限增加线程、解决同步IO

协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。

def foo():
    while True:
        x = yield
        print("value:",x)

g = foo() # g是一个生成器
next(g) # 程序运行到yield就停住了,等待下一个next
g.send(1)  # 我们给yield发送值1,然后这个值被赋值给了x,并且打印出来,然后继续下一次循环停在yield处
g.send(2)  # 同上
next(g)  # 没有给x赋值,执行print语句,打印出None,继续循环停在yield处

asyncio

asyncio的编程模型就是一个消息循环。我们从asyncio模块中直接获取一个EventLoop的引用,然后把需要执行的协程扔到EventLoop中执行,就实现了异步IO。

Python3.4

import asyncio

@asyncio.coroutine # 把一个generator标记为coroutine类型,丢到EventLoop执行
def hello():
    print("Hello world!")
    # 异步调用asyncio.sleep(1):
    r = yield from asyncio.sleep(1) # 不会等待直接中断并执行下一个消息循环,返回时执行下一语句
    print("Hello again!")

# 获取EventLoop:
loop = asyncio.get_event_loop()
# 执行coroutine
tasks = [hello(), hello()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

# 输出
Hello world! (<_MainThread(MainThread, started 140735195337472)>)
Hello world! (<_MainThread(MainThread, started 140735195337472)>)
(暂停约1秒)
Hello again! (<_MainThread(MainThread, started 140735195337472)>)
Hello again! (<_MainThread(MainThread, started 140735195337472)>)

python3.5 引入async(@asyncio.coroutine) await(yield from)

async def hello():
    print("Hello world!")
    r = await asyncio.sleep(1)
    print("Hello again!")

aiohttp则是基于asyncio实现的HTTP框架

发表评论