Công cụ thành viên

Công cụ trang web


script:feature:lua_bai_hd_6

🌟 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

script/feature/lua_bai_hd_6.txt · Sửa đổi lần cuối: 2025/07/04 04:36 bởi leo