Can you summarize the following document?
        
  協程可以通過yield(取其“讓步”之義而非“出產”)來呼叫其它協程,接下來的每次協程被呼叫時,從協程上次yield返回的位置接著執行,通過yield方式轉移執行權的協程之間不是呼叫者與被呼叫者的關係,而是彼此對稱、平等的。由於協程不如子例程那樣被普遍所知,下面對它們作簡要比較: 子例程可以看作是特定狀況的協程,任何子例程都可轉寫為不呼叫yield的協程。

  這裡是一個簡單的例子證明協程的實用性。假設這樣一種生產者-消費者的關係,一個協程生產產品並將它們加入佇列,另一個協程從佇列中取出產品並消費它們。偽碼錶示如下:  佇列用來存放產品的空間有限,同時制約生產者和消費者:為了提高效率,生產者協程要在一次執行中儘量向佇列多增加產品,然後再放棄控制使得消費者協程開始執行;同樣消費者協程也要在一次執行中儘量從佇列多取出產品,從而倒出更多的存放產品空間,然後再放棄控制使得生產者協程開始執行。儘管這個例子常用來介紹多執行緒,實際上簡單明瞭的使用協程的yield即可實現這種協作關係。

  協程非常類似於執行緒。但是協程是協作式多工的,而執行緒典型是搶佔式多工的。這意味著協程提供併發性而非並行性。協程超過執行緒的好處是它們可以用於硬性實時的語境(在協程之間的切換不需要涉及任何系統呼叫或任何呼叫),這裡不需要用來守衛關鍵區段的同步性原語(primitive)比如互斥鎖、訊號量等,並且不需要來自作業系統的支援。有可能以一種對呼叫程式碼透明的方式,使用搶佔式排程的執行緒實現協程,但是會失去某些利益(特別是對硬性實時操作的適合性和相對廉價的相互之間切換)。  纖程是協作式多工的輕量級執行緒,本質上描述了同協程一樣的概念。其區別,如果一定要說有的話,是協程是語言層級的構造,可看作一種形式的控制流,而纖程是系統層級的構造,可看作恰巧沒有並行執行的執行緒。這兩個概念誰有優先權是爭議性的:纖程可看作為協程的一種實現,也可看作實現協程的基底。

  生成器,也叫作“半協程”,是協程的子集。儘管二者都可以yield多次,掛起(suspend)自身的執行,並允許在多個入口點重新進入,但它們特別差異在於,協程有能力控制在它讓位之後哪個協程立即接續它來執行,而生成器不能,它只能把控制權轉交給呼叫生成器的呼叫者。在生成器中的codice_1語句不指定要跳轉到的協程,而是向父例程傳遞返回值。儘管如此,仍可以在生成器設施之上實現協程,這需要通過頂層的派遣器(dispatcher)例程(實質上是)的援助,它顯式的把控制權傳遞給由生成器傳回的令牌(token)所標識出的子生成器。  在不同作者和語言之間,術語“生成器”和“迭代器”的用法有著微妙的差異。有人說所有生成器都是迭代器,生成器看起來像函式而表現得像迭代器。在Python中,生成器是迭代器構造子:它是返回迭代器的函式。

  使用協程用於狀態機或併發執行類似於使用經由尾呼叫的互遞迴,在二者情況下控制權都變更給一組例程中的另一個不同例程。但是,協程更靈活並且一般而言更有效率。因為協程是yield而非return返回,接著恢復執行而非在起點重新開始,它們有能力保持狀態,包括變數(同於閉包)和執行點二者,並且yield不限於位於尾部位置;互遞迴子例程必須要麼使用共享變數,要麼把狀態作為引數傳遞。進一步的說,每一次子例程的互遞迴呼叫都需要一個新的棧幀(除非實現了尾呼叫消去),而在協程之間傳遞控制權使用現存上下文並可簡單地通過跳轉來實現。

  協程有助於實現:

  協程起源於一種組合語言方法,但有一些高階程式語言支援它。早期的例子包括Simula、Smalltalk和Modula-2。更新近的例子是Ruby、Lua、Julia和Go。  由於續體可被用來實現協程,支援續體的程式語言也非常容易就支援協程。

  到2003年,很多最流行的程式語言,包括C語言和它的後繼者,都未在語言內或其標準庫中直接支援協程。(這在很大程度上是受基於堆疊的子例程實現的限制)。C++的Boost.Context庫是個例外,它是Boost C++ Libraries的一部分,它在POSIX、Mac OS X和Windows上支援ARM、MIPS、PowerPC、SPAR和x86的上下文切換。可以在Boost.Context之上建造協程。  在協程是某種機制的最自然的實現方式,卻不能獲得可用協程的情況下,典型的解決方法是使用閉包,它是用狀態變數(靜態變數常為布林標誌值)來在呼叫之間維持內部狀態,並轉移控制權至正確地點的子例程。基於這些狀態變數的值,在程式碼中的條件語句導致在後續呼叫時有著不同程式碼路徑的執行。另一種典型的解決方法實現一個顯式狀態機,採用某種形式的大量而複雜的或goto語句特別是“計算goto”。這種實現被認為難於理解和維護,更是想要有協程支援的動機。  在當今的主流程式設計環境裡,協程的合適的替代者是執行緒和適用範圍較小的纖程。執行緒提供了用來管理“同時”執行的程式碼段實時協作互動的功能,在支援C語言的環境中,執行緒是廣泛有效的,POSIX.1c(IEEE Std 1003.1c-1995)規定了被稱為pthreads的一個標準執行緒API,它在類Unix系統中被普遍實現。執行緒被很好地實現、文件化和支援,很多程式設計師對其也比較熟悉。但是,執行緒包括了許多強大和複雜的功能用以解決大量困難的問題,這導致了困難的學習曲線,當任務僅需要協程就可完成時,使用執行緒似乎就是用力過猛了。GNU Pth可被視為類Unix系統上纖程的代表,有人嘗試過用Windows的纖程機制實現協程。

  C標準庫裡有“非區域性跳轉”函式setjmp和longjmp,它們分別儲存和恢復:棧指標、程式計數器、被呼叫者儲存的暫存器和ABI要求的任何其他內部狀態。在C99標準中,跳轉到已經用codice_2或codice_3終止的函式是未定義的<ref name="ISO/IEC 9899:1999">ISO/IEC 9899:1999, 2005, 7.13.2.1:2 and footnote 211</ref>,但是大多數codice_3實現在跳轉時不專門銷燬呼叫棧中的區域性變數,在被後續的函式呼叫等覆寫之前跳轉回來恢復時仍是原樣,這允許在實現協程時謹慎的用到它們。  POSIX.1-2001/SUSv3和此前的SUSv2進一步提供了操縱的強力設施:,可方便地用來實現協程,但是由於codice_5的引數定義不符合C99標準要求,這些函式在POSIX.1-2004中被廢棄,並在POSIX.1-2008中被刪除。POSIX.1-2001/SUSv3和此前的SUSv2定義了codice_6,可用來在不能獲得codice_5的情況下稍微迂迴的實現協程。極簡實現不採用有關的標準API函式進行上下文交換,而是寫一小塊內聯彙編只對換棧指標和程式計數器故而速度明顯的要更快。  由於缺乏直接的語言支援,很多作者寫了自己的含藏上述技術細節的協程庫,以Russ Cox的libtask協程庫為代表,它自稱能夠“寫事件驅動程式而沒有麻煩的事件”,並可用在FreeBSD、Linux、Mac OS X和SunOS之上。知名的實現還有:libpcl、lthread、libCoroutine、libconcurrency、libcoro、ribs2、libdill、libaco、libco等等。  此外人們做了用C語言的子例程和巨集實現協程的大量嘗試,並取得了不同程度的成功。Simon Tatham作出的貢獻是這一方法的很好示例,它受到了達夫裝置利用swtich語句“掉落”特性的啟發,並且是Protothreads和類似實現的基礎。這種方法的確可以提高程式碼段的可寫性、可讀性,但可維護性是存在爭議的。這種不為每個協程維護獨立的棧幀的實現方式主要缺點是,區域性變數在經過從函式yield之後是不儲存的,控制權只能從頂層例程yield。

  Python 2.5基於擴充套件的生成器實現對類似協程功能的更好支援。Python 3.3通過支援委託給子生成器增進了這個能力。Python 3.4介入了綜合性的非同步I/O框架準化,包括了利用子生成器委託的協程。Python 3.5通過async/await語法介入了對協程的顯式支援。從Python 3.7開始async/await成為保留關鍵字。

  從 Tcl 8.6 開始,Tcl 核心內建協程支援,成為了繼事件迴圈、執行緒後的另一種內建的強大功能。
運動舞(dancesport),是在社交舞基礎上發展而來的競技性舞蹈比賽。競技舞蹈分為兩類,即國際標準舞(International Standard)和國際拉丁舞(International Latin),合稱為國際風格(International Style),而每種類別又各五項舞蹈組成。世界大多數國家的舞蹈比賽主要是國家標準舞和國際拉丁舞。在美國,除了國際舞之外,還有美式舞,分別稱作美式流暢舞(American Smooth)和美式節奏舞(American Rhythm),稱為美式風格(American Style)。