- Lua 教程
- Lua - 首頁
- Lua 基礎
- Lua - 概述
- Lua - 環境
- Lua - 基本語法
- Lua - 註釋
- Lua - 列印 Hello World
- Lua - 變數
- Lua - 資料型別
- Lua - 運算子
- Lua - 迴圈
- Lua - 條件語句
- Lua - 函式
- Lua - 日期和時間
- Lua 陣列
- Lua - 陣列
- Lua - 多維陣列
- Lua - 陣列長度
- Lua - 迭代陣列
- Lua 迭代器
- Lua - 迭代器
- Lua 列表
- Lua - 在列表中搜索
- Lua 模組
- Lua - 模組
- Lua - 名稱空間
- Lua 元表
- Lua - 元表
- Lua 協程
- Lua協程
- Lua 檔案處理
- Lua - 檔案 I/O
- Lua 庫
- Lua - 標準庫
- Lua - 數學庫
- Lua - 作業系統功能
- Lua 有用資源
- Lua - 快速指南
- Lua - 有用資源
- Lua - 討論
Lua協程
簡介
協程本質上是協作式的,它允許以受控的方式執行兩種或多種方法。使用協程時,在任何給定時間,只有一個協程執行,並且此執行的協程僅在其顯式請求暫停時才會暫停其執行。
上述定義可能看起來含糊不清。讓我們假設我們有兩個方法,一個是主程式方法,另一個是協程。當我們使用 resume 函式呼叫協程時,它開始執行;當我們呼叫 yield 函式時,它暫停執行。同一個協程可以使用另一個 resume 函式呼叫從暫停的地方繼續執行。這個過程可以持續到協程執行結束。
協程中可用的函式
下表列出了 Lua 中所有可用的協程函式及其對應的用途。
| 序號 | 方法及用途 |
|---|---|
| 1 |
使用函式 f 建立一個新的協程,並返回一個“執行緒”型別的物件。 |
| 2 |
恢復協程 co 並傳遞引數(如有)。它返回操作狀態和可選的其他返回值。 |
| 3 |
返回正在執行的協程,如果在主執行緒中呼叫則返回 nil。 |
| 4 |
根據協程的狀態返回執行中、正常、暫停或死亡等值之一。 |
| 5 |
與 |
| 6 |
暫停正在執行的協程。傳遞給此方法的引數作為 resume 函式的附加返回值。 |
示例
讓我們來看一個例子來理解協程的概念。
main.lua
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))
輸出
執行上述程式時,將得到以下輸出。
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 函式啟動操作,使用 yield 函式停止操作。此外,您可以看到協程的 resume 函式接收多個返回值。
首先,我們建立一個協程並將其賦值給變數名 co,協程接收兩個變數作為引數。
當我們呼叫第一個 resume 函式時,值 3 和 2 保留在臨時變數 value1 和 value2 中,直到協程結束。
為了讓您理解這一點,我們使用了 tempvar3,它最初為 10,並且由於 value1 在協程執行過程中始終保持為 3,因此它通過後續的協程呼叫更新為 13 和 16。
第一個
coroutine.yield將兩個值 4 和 3 返回給 resume 函式,我們透過更新 yield 語句中的輸入引數 3 和 2 來獲得這些值。它還接收協程執行的真/假狀態。關於協程的另一件事是如何處理 resume 呼叫的下一個引數,在上面的例子中;您可以看到變數
coroutine.yield接收下一個呼叫的引數,這提供了一種強大的方法來使用現有引數值的關係執行新操作。最後,一旦協程中的所有語句都執行完畢,後續呼叫將返回 false 和“無法恢復已死亡的協程”語句作為響應。
另一個協程示例
讓我們來看一個簡單的協程,它使用 yield 函式和 resume 函式返回 1 到 5 的數字。如果協程不存在,則建立協程;否則恢復現有的協程。
main.lua
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
輸出
執行上述程式時,將得到以下輸出。
1 1 2 2 3 3 4 4 5 5 6 1 7 2 8 3 9 4 10 5
協程經常與多程式語言的執行緒進行比較,但我們需要理解的是,協程具有與執行緒類似的功能,但它們一次只執行一個,永遠不會併發執行。
我們控制程式執行順序以滿足需求,並臨時保留某些資訊。在協程中使用全域性變數為協程提供了更大的靈活性。