在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Java/ 協(xié)程
數(shù)據(jù)庫訪問
循環(huán)
數(shù)組
錯誤處理
面向?qū)ο?/span>
調(diào)試
游戲開發(fā)
文件 I/O
變量
迭代器
Web 編程
模塊
函數(shù)
元表
協(xié)程
垃圾回收機制
標準庫
決策
數(shù)據(jù)類型
運行環(huán)境
操作符
字符串
基本語法
概述

協(xié)程

概述

協(xié)程具有協(xié)同的性質(zhì),它允許兩個或多個方法以某種可控的方式協(xié)同工作。在任何一個時刻,都只有一個協(xié)程在運行,只有當正在運行的協(xié)程主動掛起時它的執(zhí)行才會被掛起(暫停)。

上面的定義可能看上去比較模糊。接下來讓我講得很清楚一點,假設我們有兩個方法,一個是主程序方法,另一個是一個協(xié)程。當我們使用 resume 函數(shù)調(diào)用一個協(xié)程時,協(xié)程才開始執(zhí)行。當在協(xié)程調(diào)用 yield 函數(shù)時,協(xié)程掛起執(zhí)行。再次調(diào)用 resume 函數(shù)時,協(xié)程再從上次掛起的地方繼續(xù)執(zhí)行。這個過程一直持續(xù)到協(xié)程執(zhí)行結(jié)束為止。

協(xié)程中可用的函數(shù)

下面的表中列出 Lua 語言為支持協(xié)程而提供的所有函數(shù)以及它們的用法。

S.N. 方法和功能
1 coroutine.create(f):用函數(shù) f 創(chuàng)建一個協(xié)程,返回 thread 類型對象。
2 coroutine.resume(co[,val1,...]): 傳入?yún)?shù)(可選),重新執(zhí)行協(xié)程 co。此函數(shù)返回執(zhí)行狀態(tài),也可以返回其它值。
3 coroutine.running():返回正在運行的協(xié)程,如果在主線程中調(diào)用此函數(shù)則返回 nil。
4 coroutine.status(co):返回指定協(xié)程的狀態(tài),狀態(tài)值允許為:正在運行(running),正常(normal),掛起(suspended),結(jié)束(dead)。
5 coroutine.wrap(f):與前面 coroutine.create 一樣,coroutine.wrap 函數(shù)也創(chuàng)建一個協(xié)程,與前者返回協(xié)程本身不同,后者返回一個函數(shù)。當調(diào)用該函數(shù)時,重新執(zhí)行協(xié)程。
6 coroutine.yield(...):掛起正在執(zhí)行的協(xié)程。為此函數(shù)傳入的參數(shù)值作為執(zhí)行協(xié)程函數(shù) resume 的額外返回值(默認會返回協(xié)程執(zhí)行狀態(tài))。

示例

讓我們通過下面的例子來理解一下協(xié)程這個概念。

co = coroutine.create(function (value1,value2)
   local tempvar3 =10
   print("coroutine section 1", value1, value2, tempvar3)
   local tempvar1 = coroutine.yield(value1+1,value2+1)
   tempvar3 = tempvar3 + value1
   print("coroutine section 2",tempvar1 ,tempvar2, tempvar3)
   local tempvar1, tempvar2= coroutine.yield(value1+value2, value1-value2)
   tempvar3 = tempvar3 + value1
   print("coroutine section 3",tempvar1,tempvar2, tempvar3)
   return value2, "end"
end)

print("main", coroutine.resume(co, 3, 2))
print("main", coroutine.resume(co, 12,14))
print("main", coroutine.resume(co, 5, 6))
print("main", coroutine.resume(co, 10, 20))

執(zhí)行上面的程序,我們可以得到如下的輸出結(jié)果:

coroutine section 1 3   2   10
main    true    4   3
coroutine section 2 12  nil 13
main    true    5   1
coroutine section 3 5   6   16
main    true    2   end
main    false   cannot resume dead coroutine

上面的例子到底做了些什么呢?

和前面說到的一樣,在例子中我們使用 resume 函數(shù)繼續(xù)執(zhí)行協(xié)程,用 yield 函數(shù)掛起協(xié)程。同樣,從例子中也可以看出如何為執(zhí)行協(xié)程的 resueme 函數(shù)返回多個值。下面我將逐步解釋上面的代碼。

  • 首先,我們創(chuàng)建了一個協(xié)程并將其賦給變量 co。此協(xié)程允許傳入兩個參數(shù)。
  • 第一次調(diào)用函數(shù) resume 時,協(xié)程內(nèi)局部變量 value1 和 value2 的值分別為 3 和 2。
  • 為了便于理解,我們使用了局部變量 tempvar3 該變量被初始化為 10。由于變量 value1 的值為3,所以 tempvar3 在隨后的協(xié)程調(diào)用過程中被先后更新為 13 和 16。
  • 第一次調(diào)用 coroutine.yield 時,為 resume 函數(shù)返回了值 4 和 3,這兩個值是由傳入的參數(shù) 3,2 分別加 1 后的結(jié)果,這一點可以從 yield 語句中得到證實。除了顯示指定的返回值外,resume 還收到隱式的返回值 true,該值表示協(xié)程執(zhí)行的狀態(tài),有 true 和 false 兩個可能取值。
  • 上面的例子中,我們還應該關注在下一次調(diào)用 resume 時如何為協(xié)程傳入?yún)?shù)。從例子中可以看到,coroutine.yield 函數(shù)返回后為兩個變量賦值,該值即是第二次調(diào)用 resume 時傳入的參數(shù)。這種參數(shù)傳遞的機制讓可以結(jié)合前面?zhèn)魅氲膮?shù)完成很多新的操作。
  • 最后,協(xié)程中所有語句執(zhí)行完后,后面的調(diào)用就會返回 false 狀態(tài),同時返回 "cannot resume dead coroutine"消息。

另一個協(xié)程的示例

下面這例子中的協(xié)程使用 yield 函數(shù)和 resume 函數(shù)依次返回數(shù)字 1 到 5。示例中,如果沒有協(xié)程對象或?qū)ο笠呀Y(jié)束(dead),則重新創(chuàng)建一個新的協(xié)程對象;若協(xié)程已經(jīng)存在,則執(zhí)行已經(jīng)存在的協(xié)程。

function getNumber()
   local function getNumberHelper()
      co = coroutine.create(function ()
      coroutine.yield(1)
      coroutine.yield(2)
      coroutine.yield(3)
      coroutine.yield(4)
      coroutine.yield(5)
      end)
      return co
   end
   if(numberHelper) then
      status, number = coroutine.resume(numberHelper);
      if coroutine.status(numberHelper) == "dead" then
         numberHelper = getNumberHelper()
         status, number = coroutine.resume(numberHelper);
      end
      return number
   else
      numberHelper = getNumberHelper()
      status, number = coroutine.resume(numberHelper);
      return number
   end
end
for index = 1, 10 do
   print(index, getNumber())
end

執(zhí)行上述的程序,我們可以得到如下的輸出結(jié)果:

1   1
2   2
3   3
4   4
5   5
6   1
7   2
8   3
9   4
10  5

大家經(jīng)常會把協(xié)程和多線程編程語言中的線程進行對比,但我們要明白,協(xié)程有著與線程類似的特性,但是協(xié)程與線程的區(qū)別在于協(xié)程不能并發(fā),任意時刻只會有一個協(xié)程執(zhí)行,而線程允許并發(fā)的存在。(譯注:譯者認為本質(zhì)上協(xié)程其是就是線程,不過是用戶態(tài)的線罷了,它將調(diào)度問題交由程序開發(fā)人員手動完成。)

我們通過控制程序執(zhí)行順序以滿足獲取某些臨時信息的需求。配合全局變量的使用,協(xié)和會變得更加的靈活方便。

上一篇:函數(shù)下一篇:基本語法