======🌟 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
----