0Pricing
Lua Academy · บทเรียน

สถานะโคโรทีน

ตรวจสอบสถานะโคโรทีนด้วย coroutine.status ได้แก่ running, suspended และ dead

สถานะโคโรทีน เป็นบทเรียน Lua Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Lua Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน

สถานะของโครูทีนสี่สถานะ

โครูทีนมีสถานะที่เป็นไปได้สี่สถานะ ได้แก่ ถูกพัก (สร้างขึ้นหรือ yield แล้วและกำลังรอทำงาน), กำลังทำงาน (กำลังประมวลผลอยู่), ปกติ (หยุดชั่วคราวเพื่อให้โครูทีนอื่นทำงาน) และ สิ้นสุด (ทำงานเสร็จหรือเกิดข้อผิดพลาด) ตรวจสอบสถานะด้วย coroutine.status(co)

local co = coroutine.create(function()
  print(coroutine.status(coroutine.running()))  -- running
  coroutine.yield()
end)

print(coroutine.status(co))  -- suspended
coroutine.resume(co)          -- prints: running
print(coroutine.status(co))  -- suspended
coroutine.resume(co)
print(coroutine.status(co))  -- dead

สถานะ “ปกติ”

โครูทีนจะเข้าสู่สถานะ “ปกติ” เมื่อดำเนินการต่อให้โครูทีนอื่น โครูทีนนี้ไม่ได้กำลังทำงาน (เพราะโครูทีนอื่นกำลังทำงานอยู่) แต่ก็ไม่ได้ถูกพักเช่นกัน เพราะกำลังรอให้โครูทีนที่ดำเนินการต่อ yield สถานะนี้พบไม่บ่อย แต่สำคัญต่อการทำความเข้าใจกราฟโครูทีนที่ซับซ้อน

local inner, outer

inner = coroutine.create(function()
  print("outer status:", coroutine.status(outer))  -- normal
  coroutine.yield()
end)

outer = coroutine.create(function()
  coroutine.resume(inner)
end)

coroutine.resume(outer)
-- prints: outer status: normal

ตรวจสอบก่อนดำเนินการต่อ

ควรตรวจสอบสถานะของโครูทีนก่อนดำเนินการต่อเสมอ โดยเฉพาะในลูป การดำเนินการต่อให้โครูทีนที่สิ้นสุดแล้วถือเป็นข้อผิดพลาด การดำเนินการต่อให้โครูทีนที่กำลังทำงานอยู่ก็เป็นข้อผิดพลาดเช่นกัน เพราะจะทำให้เกิดการเรียกซ้ำไม่สิ้นสุด

local function safeResume(co, ...)
  local status = coroutine.status(co)
  if status == "dead" then
    return false, "cannot resume dead coroutine"
  end
  if status == "running" then
    return false, "cannot resume running coroutine"
  end
  return coroutine.resume(co, ...)
end

สถานะหลังเกิดข้อผิดพลาด

เมื่อโค้ดในตัวโครูทีนทำให้เกิดข้อผิดพลาดที่ไม่ได้ดักจับ coroutine.resume จะส่งคืน false และข้อความข้อผิดพลาด โครูทีนจะเปลี่ยนเป็นสถานะ “สิ้นสุด” และไม่สามารถเริ่มใหม่ได้ หากต้องการลองอีกครั้ง คุณต้องสร้างโครูทีนตัวใหม่

local co = coroutine.create(function()
  error("something went wrong")
end)

local ok, err = coroutine.resume(co)
print(ok, err)                      -- false  ...: something went wrong
print(coroutine.status(co))         -- dead

-- Cannot resume dead coroutine:
local ok2, err2 = coroutine.resume(co)
print(ok2, err2)  -- false  cannot resume dead coroutine

coroutine.isyieldable

coroutine.isyieldable() จะส่งคืน true หากโครูทีนที่กำลังทำงานสามารถ yield ได้ และจะส่งคืน false ในเธรดหลักและในฟังก์ชัน C ที่ไม่รองรับการ yield หากไม่แน่ใจเกี่ยวกับบริบท ควรตรวจสอบก่อน yield เสมอ

local co = coroutine.create(function()
  print("isyieldable:", coroutine.isyieldable())  -- true
  coroutine.yield()
end)

coroutine.resume(co)

-- In main thread:
print("isyieldable:", coroutine.isyieldable())  -- false
-- coroutine.yield()  -- ERROR in main thread

การตรวจสอบกลุ่มโครูทีน

ติดตามพูลของโครูทีน และนำโครูทีนที่สิ้นสุดแล้วออกหลังการดำเนินการต่อแต่ละรอบ นี่คือพื้นฐานของตัวจัดตารางงาน

local function makeWorker(n, name)
  return coroutine.create(function()
    for i = 1, n do
      print(name, "step", i)
      coroutine.yield()
    end
  end)
end

local workers = {
  makeWorker(2, "fast"),
  makeWorker(4, "slow"),
}

while #workers > 0 do
  local alive = {}
  for _, co in ipairs(workers) do
    coroutine.resume(co)
    if coroutine.status(co) ~= "dead" then
      alive[#alive+1] = co
    end
  end
  workers = alive
end

การแก้ไขข้อบกพร่องของโครูทีน

ใช้การตรวจสอบสถานะเพื่อแทรกเครื่องมือวัดและแก้ไขข้อบกพร่องของโค้ดที่ใช้โครูทีน พิมพ์การเปลี่ยนแปลงสถานะเพื่อทำความเข้าใจลำดับการทำงาน ในระบบที่ซับซ้อน ให้กำหนดชื่อแก่โครูทีนผ่านตารางตัวห่อหุ้ม เพื่อให้ผลลัพธ์การแก้ไขข้อบกพร่องอ่านได้ง่ายขึ้น

local function namedCo(name, fn)
  local co = coroutine.create(fn)
  return {
    co = co,
    name = name,
    resume = function(self, ...)
      print("[" .. self.name .. "] resume")
      local results = table.pack(coroutine.resume(self.co, ...))
      print("[" .. self.name .. "] status: " .. coroutine.status(self.co))
      return table.unpack(results, 1, results.n)
    end
  }
end

local worker = namedCo("worker1", function()
  coroutine.yield()
end)
worker:resume()
worker:resume()

การเริ่มโครูทีนที่สิ้นสุดแล้วใหม่

เมื่อโครูทีนสิ้นสุดแล้ว จะไม่สามารถดำเนินการต่อได้ หากต้องการ “เริ่มใหม่” คุณต้องสร้างโครูทีนตัวใหม่จากฟังก์ชันเดิม รูปแบบที่ใช้กันทั่วไปคือโรงงานที่สร้างโครูทีนใหม่เมื่อจำเป็น

local function makeCounter(start, step)
  return coroutine.wrap(function()
    local n = start or 0
    while true do
      coroutine.yield(n)
      n = n + (step or 1)
    end
  end)
end

local count = makeCounter(0, 2)
for i = 1, 5 do io.write(count() .. " ") end
print()  -- 0 2 4 6 8

-- "Restart" by creating a new one
count = makeCounter(100)
print(count())   -- 100

พฤติกรรมข้อผิดพลาดของ Coroutine.wrap

เมื่อโครูทีนที่ถูกห่อหุ้มเกิดข้อผิดพลาด ข้อผิดพลาดนั้นจะถูกส่งต่อออกมาจากการเรียกฟังก์ชันตัวห่อหุ้ม ต่างจาก coroutine.resume ที่ส่งคืน false+ข้อผิดพลาด ฟังก์ชันที่ wrap ส่งคืนจะทำให้เกิดข้อผิดพลาดโดยตรง หากต้องการดักจับข้อผิดพลาด ให้ใช้ pcall ครอบการเรียก wrap

local gen = coroutine.wrap(function()
  coroutine.yield(1)
  error("oops")
  coroutine.yield(2)  -- never reached
end)

print(gen())   -- 1 (ok)
local ok, err = pcall(gen)
print(ok, err) -- false  ...: oops
-- Subsequent call: dead coroutine
ok, err = pcall(gen)
print(ok, err) -- false  cannot resume dead coroutine

isyieldable เทียบกับ status

มีสองวิธีในการตรวจสอบบริบทของโครูทีน: coroutine.status(co) แสดงสถานะของโครูทีนที่ระบุ ส่วน coroutine.isyieldable() ระบุว่าบริบทการทำงานปัจจุบันสามารถ yield ได้หรือไม่ ใช้ status เพื่อตรวจสอบโครูทีนอื่น และใช้ isyieldable เพื่อตรวจสอบว่าคุณสามารถ yield ได้อย่างปลอดภัยหรือไม่

local function maybeYield()
  if coroutine.isyieldable() then
    coroutine.yield()
  else
    -- in main thread or non-yieldable context
    print("cannot yield here")
  end
end

maybeYield()  -- prints "cannot yield here" (main thread)

local co = coroutine.create(maybeYield)
coroutine.resume(co)   -- yields successfully

ตรวจสอบความเข้าใจอย่างรวดเร็ว

โครูทีนจะเข้าสู่สถานะใดเมื่อทำงานฟังก์ชันในตัวโครูทีนเสร็จสิ้น?

สรุป: สถานะของโครูทีน

สรุป:

  • สถานะ: ถูกพัก → กำลังทำงาน ↔ ปกติ → สิ้นสุด
  • coroutine.status(co) ส่งคืนสตริงสถานะ
  • สิ้นสุด = ทำงานเสร็จหรือเกิดข้อผิดพลาด จึงไม่สามารถดำเนินการต่อได้
  • coroutine.isyieldable() ตรวจสอบว่าบริบทปัจจุบันสามารถ yield ได้หรือไม่
  • ควรตรวจสอบสถานะก่อนดำเนินการต่อในลูปเสมอ
  • ข้อผิดพลาดจาก wrap ถูกส่งต่อโดยตรง ส่วน resume ส่งคืน false+ข้อผิดพลาด

คำถามที่พบบ่อย

บทเรียน “สถานะโคโรทีน” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “สถานะโคโรทีน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Lua Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Lua Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “สถานะโคโรทีน”

ตรวจสอบสถานะโคโรทีนด้วย coroutine.status ได้แก่ running, suspended และ dead คุณปฏิบัติ Lua Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Lua Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Lua Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “สถานะโคโรทีน” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Lua Academy นี้ได้ไหม

ได้ บทเรียน Lua Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การสร้างโคโรทีน
  2. resume และ yield
  3. สถานะโคโรทีน
  4. รูปแบบผู้ผลิต-ผู้บริโภค
← กลับไปที่ Lua Academy