python18协程
协程是我们自己调度的
进程是系统调度的
协程切换很少开销
python3.5之前的实现方法
def yield_test(): """实现协程函数""" while True: n = (yield) print(n) if __name__ == "__main__": rest = yield_test() next(rest) rest.send("666") rest.send("666") 结果: 666 666
python3.6之后
例如当我们读文件的时候,文件比较大,读的时候可能会有阻塞,这时候我们使用await方法,让loop调用其他的协程,
等到读完之后再回来执行
import asyncio async def do_sth(x): """定义协程函数""" print("等待中{}".format(x)) await asyncio.sleep(x) #判断是否为协程函数 print(asyncio.iscoroutinefunction(do_sth)) coroutine = do_sth(5) #事件循环队列 loop = asyncio.get_event_loop() #注册任务 task = loop.create_task(coroutine) print(task) #等待协程任务执行结束 loop.run_until_complete(task) print(task) 结果; True <Task pending coro=<do_sth() running at D:/PycharmProjects/untitled0406/test.py:4>> 等待中5 <Task finished coro=<do_sth() done, defined at D:/PycharmProjects/untitled0406/test.py:4> result=None>
执行过程
创建协程函数 获取事件循环队列 将协程函数加入到事件队列形成任务 等待协程任务执行结束
import asyncio async def compute(x,y): print("计算x + y => {0}+{1}".format(x,y)) await asyncio.sleep(3) return x + y async def get_sum(x,y): rest = await compute(x,y) print("{0} + {1} = {2}".format(x,y,rest)) #拿到事件循环 loop = asyncio.get_event_loop() loop.run_until_complete(get_sum(1,2)) loop.close() 结果: 计算x + y => 1+2 1 + 2 = 3
#定义一个队列 #让两个协程来进行通信 #让其中一个协程往队列中写数据 #让另一个协程从队列中删除数据 import asyncio import random async def add(store,name): """ 写入数据到队列 :param store: 队列的对象 :return: """ for i in range(5): #往队列添加数字 num = "{0} - {1}".format(name,i) await asyncio.sleep(random.randint(1, 5)) await store.put(i) print("{2}add one ... {0},size:{1}".format(num,store.qsize(),name)) async def reduce(store): """ 从队列中删除数据 :param store: :return: """ for i in range(10): rest = await store.get() print("reduce one ....{0},size{1}".format(rest,store.qsize())) if __name__ == "__main__": #准备队列 store = asyncio.Queue(maxsize=5) a1 = add(store,"a1111") a2 = add(store,"a2222") r1 = reduce(store) #添加事件队列 loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.gather(a1,a2,r1)) loop.close()
结果;
a2222add one ... a2222 - 0,size:1 reduce one ....0,size0 a1111add one ... a1111 - 0,size:1 reduce one ....0,size0 a2222add one ... a2222 - 1,size:1 reduce one ....1,size0 a1111add one ... a1111 - 1,size:1 reduce one ....1,size0 a1111add one ... a1111 - 2,size:1 reduce one ....2,size0 a2222add one ... a2222 - 2,size:1 a1111add one ... a1111 - 3,size:2 reduce one ....2,size1 reduce one ....3,size0 a1111add one ... a1111 - 4,size:1 reduce one ....4,size0 a2222add one ... a2222 - 3,size:1 reduce one ....3,size0 a2222add one ... a2222 - 4,size:1 reduce one ....4,size0