c++ 协程_用yield实现协程
上一篇 理解python中的yield關鍵字 介紹了使用yeld實現生成器函數,這一篇我們來繼續深入的了解一下yield,用yield實現協程。
先來解答一下上一篇留下的問題:下面的代碼為什么第二次調用next打印None呢?
def事實是這樣的,yield語句默認返回None。當第一次調用next方法時,生成器函數開始執行,執行到yield表達式為止,但此時賦值操作并為執行。上面的代碼中,在第一次調用next的時候,echo生成了1。第二次調用next的時候,yield表達式的值賦給了n,n此時變成None了,再次yield n的時候就自然生成None了。
好了,接下來開始本文的主題。
什么是協程
引用官方的說法:
協程是一種用戶態的輕量級線程,協程的調度完全由用戶控制。協程擁有自己的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操作棧則基本沒有內核切換的開銷,可以不加鎖的訪問全局變量,所以上下文的切換非常快。與線程相比,協程更輕量。一個Python線程大概占用8M內存,而一個協程只占用1KB不到內存。協程更適用于IO密集型的應用。
在講述協程的實現前,我們有必要先來看一下send方法。
send方法
yield表達式有一個返回值,send方法的作用就是控制這個返回值,send的參數就是yield表達式的返回值。我們來看一下官方文檔上關于send的定義
generate.send(value):生成器的send(value)方法會將value值“發送”給生成器中的方法。value參數變成當前yield表達式的值。send()方法會返回生成器生成的下一個yield值或者StopIteration異常(如果生成器沒有生成下一個yield值就退出了)。當通過調用send()啟動生成器時,value值必須為None,因為當前還沒有yield表達式可以接收參數。
是不是看暈了?我們來看一個例子
def上面的代碼輸出
before yield after yield: 1 before yield after yield: 2 before yield after yield: None before yield第一次調用next的時候,程序從函數最開始處運行,打印出
before yield
執行到yield處,停在該處。
接下來,向生成器send(1)。send在這里起到兩個作用,一個是將參數值賦給yield的返回值,然后該返回值賦給了變量x;一個是繼續程序的執行,直到下一次遇到yield停下來。第二個功能和next類似。其實,next 就相當于 send(None) 。
執行了 send(1) 后,x被賦值給yield的返回值,即send的參數1,并繼續往下執行,打印出了
after yield: 1
繼續執行,回到循環的開始,向下執行,打印出
before yield
再次遇到yield,停在該處,等待下一次send或next的調用。
向生成器send(2)。這里的步驟和 send(1) 相同,打印出下面兩條后,在yield處停住。
after yield: 2
before yield
執行 next(g),x被賦值為yield表達式的返回值,也就是None,繼續向下執行,打印出
after yield: None
再次回到循環的開始,向下執行,打印出
before yield
程序運行結束。
現在是不是有點理解send了?
yield和send實現Python協程
我們來用協程實現一個生產者/消費者的例子
import運行上面的程序,會輸出
[producer] producing 1... [consumer] consuming 1... [producer] consumer return: well received [producer] producing 2... [consumer] consuming 2... [producer] consumer return: well received [producer] producing 3... [consumer] consuming 3... [producer] consumer return: well received [producer] producing 4... [consumer] consuming 4... [producer] consumer return: well received [producer] producing 5... [consumer] consuming 5... [producer] consumer return: well receivedproduce函數負責生產數據,consume函數負責消費數據。具體執行過程如下:
produce和consume函數在一個線程內執行,通過調用send方法和yield互相切換,實現協程的功能。
總結
以上是生活随笔為你收集整理的c++ 协程_用yield实现协程的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: c++ 操作mysql_C++操作mys
- 下一篇: 清华大学镜像_国内开源镜像站信息盘点
