Python协程:从yield/send到async/await
生活随笔
收集整理的這篇文章主要介紹了
Python协程:从yield/send到async/await
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這個文章理好了脈落。
http://python.jobbole.com/86069/
我練 習了一番,感受好了很多。。。
Python由于眾所周知的GIL的原因,導致其線程無法發揮多核的并行計算能力(當然,后來有了multiprocessing,可以實現多進程并行),顯得比較雞肋。既然在GIL之下,同一時刻只能有一個線程在運行,那么對于CPU密集的程序來說,線程之間的切換開銷就成了拖累,而以I/O為瓶頸的程序正是協程所擅長的:
多任務并發(非并行),每個任務在合適的時候掛起(發起I/O)和恢復(I/O結束)
弄清楚了asyncio.coroutine和yield from之后,在Python3.5中引入的async和await就不難理解了:可以將他們理解成asyncio.coroutine/yield from的完美替身。當然,從Python設計的角度來說,async/await讓協程表面上獨立于生成器而存在,將細節都隱藏于asyncio模塊之下,語法更清晰明了。
#!/usr/bin/env python # -*- coding: utf-8 -*-import asyncio import time import random''' def old_fib(n):res = [0] * nindex = 0a = 0b = 1while index < n:res[index] = ba, b = b, a + bindex += 1return resprint("-"*10 + "test old fib " + "-"*10) for fib_res in old_fib(20):print(fib_res)def fib(n):index = 0a = 0b = 1while index < n:yield ba, b = b, a + bindex += 1print("-"*10 + "test yield fib " + "-"*10) for fib_res in fib(20):print(fib_res)def stupid_fib(n):index = 0a = 0b = 1while index < n:sleep_cnt = yield bprint("let me think {0} secs".format(sleep_cnt))time.sleep(sleep_cnt)a, b = b, a + bindex += 1 print("-"*10 + "test yield send " + "-"*10) N = 20 sfib = stupid_fib(N) fib_res = next(sfib) while True:print(fib_res)try:fib_res = sfib.send(random.uniform(0, 0.5))except StopIteration:breakdef copy_fib(n):print("I am copy from fib")yield from fib(n)print("copy end") print("-"*10 + "test yield from " + "-"*10) for fib_res in copy_fib(20):print(fib_res)def copy_stupid_fib(n):print("I am copy from stupid fib")yield from stupid_fib(n)print("Copy end")print("-"*10 + "test yield from and send" + "-"*10) N = 20 csfib = copy_stupid_fib(N) fib_res = next(csfib) while True:print(fib_res)try:fib_res = csfib.send(random.uniform(0, 0.5))except StopIteration:break@asyncio.coroutine def smart_fib(n):index = 0a = 0b = 1while index < n:sleep_secs = random.uniform(0, 0.2)yield from asyncio.sleep(sleep_secs)print("Smart one think {} secs to get {}".format(sleep_secs, b))a, b = b, a + bindex += 1@asyncio.coroutine def stupid_fib(n):index = 0a = 0b = 1while index < n:sleep_secs = random.uniform(0, 0.4)yield from asyncio.sleep(sleep_secs)print("Stupid one think {} secs to get {}".format(sleep_secs, b))a, b = b, a + bindex += 1loop = asyncio.get_event_loop() tasks = [asyncio.async(smart_fib(10)),asyncio.async(stupid_fib(10)),] loop.run_until_complete(async.wait(tasks)) print("All fib finished.") loop.close()'''async def smart_fib(n):index = 0a = 0b = 1while index < n:sleep_secs = random.uniform(0, 0.2)await asyncio.sleep(sleep_secs)print("Smart one think {} secs to get {}".format(sleep_secs, b))a, b = b, a + bindex += 1async def stupid_fib(n):index = 0a = 0b = 1while index < n:sleep_secs = random.uniform(0, 0.4)await asyncio.sleep(sleep_secs)print("Stupid one think {} secs to get {}".format(sleep_secs, b))a, b = b, a + bindex += 1loop = asyncio.get_event_loop() tasks = [asyncio.async(smart_fib(10)),asyncio.async(stupid_fib(10)),] loop.run_until_complete(asyncio.wait(tasks)) print("All fib finished.") loop.close()Python中的協程經歷了很長的一段發展歷程。其大概經歷了如下三個階段:
總結
以上是生活随笔為你收集整理的Python协程:从yield/send到async/await的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode 题解汇总
- 下一篇: 金额大小写转换(1)