Lua 的協同程式 是一種使用者層級的輕量級執行緒,擁有獨立堆疊、區域變數與指令指標,但與其他協同程式共享全域環境。與作業系統執行緒不同,協同程式採用協作式多任務:任一時刻僅有一個協同程式在執行,僅在主動呼叫 yield 時才會暫停並將控制權交還。
coroutine.create(f):建立協同程式,回傳 thread 型別值,狀態為 suspended。coroutine.resume(co, ...):啟動或恢復協同程式,回傳 true 加上 yield 的參數,或 false 加錯誤訊息。coroutine.yield(...):掛起目前協同程式,將參數傳回對應的 resume。coroutine.status(co):查詢狀態(suspended/running/dead/normal)。local co = coroutine.create(function()
for i = 1, 10 do
print("co", i)
coroutine.yield()
end
end)
print(coroutine.status(co)) -- suspended
coroutine.resume(co) -- co 1
print(coroutine.status(co)) -- suspended
coroutine.resume(co) -- co 2
-- ... 繼續 resume 直到結束
print(coroutine.status(co)) -- dead
yield 的回傳值。resume 的參數(除第一個)。function foo(a)
print("foo", a)
return coroutine.yield(2 * a)
end
co = coroutine.create(function(a, b)
print("co-body", a, b)
local r = foo(a + 1)
print("co-body2", r)
local r, s = coroutine.yield(a + b, a - b)
print("co-body3", r, s)
return b, "end"
end)
print("main", coroutine.resume(co, 1, 10)) -- true 4
print("main", coroutine.resume(co, "r")) -- true 11 -9
print("main", coroutine.resume(co, "x", "y")) -- true 10 end
print("main", coroutine.resume(co)) -- false cannot resume dead coroutine
利用協同程式的掛起/恢復機制,無需鎖即可實現同步:
local producer
function producer_fn()
local i = 0
while true do
i = i + 1
coroutine.yield(i) -- 產出資料並掛起
end
end
function consumer_fn()
while true do
local _, val = coroutine.resume(producer)
print("consumed:", val)
end
end
producer = coroutine.create(producer_fn)
consumer_fn()
此模式下,生產者與消費者在同一執行緒內交替執行,資料流向清晰且無競態條件。
resume 若回傳 false,第二個值為錯誤訊息。協同程式內部錯誤不會直接中斷主程式,而是透過 resume 回傳,便於統一處理。
協同程式以非搶佔式排程提供輕量並發,適合實現狀態機、非同步 I/O 封裝、生產者-消費者等模式。掌握 resume/yield 的資料交換語意,是編寫高效 Lua 程式的關鍵。