Mục lục
🌟 Giới thiệu về Coroutine trong Lua
📌 Khái niệm cơ bản về Coroutine
🛠️ Tạo Coroutine:
Một coroutine trong Lua được tạo bằng hàm coroutine.create, nhận vào một hàm Lua và trả về một coroutine.
📜 Ví dụ mã:
function foo() print("Coroutine started") coroutine.yield() print("Coroutine resumed") end
co = coroutine.create(foo)
▶️ Chạy Coroutine:
Để bắt đầu hoặc tiếp tục coroutine, dùng coroutine.resume. Hàm này sẽ chạy coroutine cho đến khi nó yield hoặc kết thúc.
coroutine.resume(co) -- Output: Coroutine started coroutine.resume(co) -- Output: Coroutine resumed
⏸️ Tạm dừng Coroutine:
Bên trong coroutine, bạn có thể tạm dừng thực thi bằng coroutine.yield. Điều này cho phép coroutine trả quyền điều khiển về cho hàm gọi, và có thể được tiếp tục sau đó.
function bar() for i = 1, 3 do print("Iteration", i) coroutine.yield() end end co = coroutine.create(bar) for i = 1, 3 do coroutine.resume(co) end -- Output: Iteration 1, 2, 3
📊 Trạng thái của Coroutine
Bạn có thể kiểm tra trạng thái coroutine bằng coroutine.status. Các trạng thái có thể là:
- “running”: Coroutine đang chạy
- “suspended”: Coroutine đang tạm dừng, có thể tiếp tục
- “normal”: Coroutine đang hoạt động nhưng không chạy (đã gọi yield)
- “dead”: Coroutine đã hoàn tất
print(coroutine.status(co)) -- Output: suspended (sau lần yield đầu) coroutine.resume(co) print(coroutine.status(co)) -- Output: dead (sau khi kết thúc)
🔧 Các hàm Coroutine trong Lua
Lua cung cấp một số hàm để làm việc với coroutine:
- coroutine.create(f): Tạo một coroutine với hàm f
- coroutine.resume(co, …): Tiếp tục coroutine co, truyền đối số nếu có
- coroutine.yield(…): Tạm dừng coroutine, có thể trả giá trị về hàm gọi
- coroutine.status(co): Trả về trạng thái của co
- coroutine.running(): Trả về coroutine đang chạy
📦 Ví dụ 1: Coroutine với đối số
Bạn có thể truyền đối số vào coroutine và sử dụng trong hàm.
function greet(name) print("Hello, " .. name) coroutine.yield() print("Goodbye, " .. name) end co = coroutine.create(greet) coroutine.resume(co, "Alice") -- Output: Hello, Alice coroutine.resume(co) -- Output: Goodbye, Alice
🔁 Ví dụ 2: Truyền giá trị qua lại
Coroutines có thể yield và trả giá trị về hàm gọi.
function add(a, b) coroutine.yield(a + b) end co = coroutine.create(add) success, result = coroutine.resume(co, 5, 7) print(result) -- Output: 12
📈 Ví dụ 3: Sinh dãy Fibonacci
Coroutine có thể dùng để tạo các chuỗi số như Fibonacci.
function fibonacci() local a, b = 0, 1 while true do coroutine.yield(a) a, b = b, a + b end end co = coroutine.create(fibonacci) for i = 1, 10 do success, value = coroutine.resume(co) print(value) end -- Output: 10 số đầu tiên trong dãy Fibonacci
🔄 Ví dụ 4: Mô hình Producer – Consumer
Coroutine có thể thực hiện mô hình sản xuất – tiêu thụ.
function producer() local i = 0 while true do i = i + 1 coroutine.yield(i) end end function consumer() while true do local status, value = coroutine.resume(pro) print("Consumed: " .. value) end end pro = coroutine.create(producer) consumer() -- In ra vô hạn các giá trị được tạo
⚙️ Ví dụ 5: State Machine đơn giản
Coroutine giúp xây dựng state machine đơn giản.
function state_a() print("In State A") coroutine.yield("go to B") print("Returning to State A") end function state_b() print("In State B") coroutine.yield("go to A") end state = {A = coroutine.create(state_a), B = coroutine.create(state_b)} current_state = "A" while true do local status, next_state = coroutine.resume(state[current_state]) if not status then break end current_state = (next_state == "go to A") and "A" or "B" end
🕹️ Ví dụ 6: Lập lịch Round-Robin
Sử dụng coroutine để thực hiện lập lịch xoay vòng giữa các tác vụ.
function task1() for i = 1, 3 do print("Task 1, iteration " .. i) coroutine.yield() end end function task2() for i = 1, 3 do print("Task 2, iteration " .. i) coroutine.yield() end end tasks = {coroutine.create(task1), coroutine.create(task2)} while true do local all_done = true for i = 1, #tasks do if coroutine.status(tasks[i]) ~= "dead" then coroutine.resume(tasks[i]) all_done = false end end if all_done then break end end