Lua Academy · Pelajaran

Mencipta Coroutine

Cipta coroutine dengan coroutine.create dan coroutine.wrap.

Pelajaran 1 daripada 412 langkah

Mencipta Coroutine ialah pelajaran Lua Academy percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Lua Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Lua Academy merangkumi sejumlah 4 pelajaran.

Apakah Coroutine?

Coroutine ialah fungsi yang boleh menjeda pelaksanaannya (yield) dan kemudian menyambung semula dari tempat ia berhenti. Tidak seperti bebenang, coroutine bersifat kooperatif — hanya satu yang berjalan pada satu-satu masa, dan coroutine melepaskan kawalan secara jelas. Coroutine Lua mempunyai tindanan dan pemboleh ubah setempat sendiri.

local co = coroutine.create(function()
  print("start")
  coroutine.yield()
  print("resumed")
  coroutine.yield()
  print("done")
end)

print(coroutine.status(co))   -- suspended
coroutine.resume(co)          -- start
print(coroutine.status(co))   -- suspended
coroutine.resume(co)          -- resumed

coroutine.create berbanding coroutine.wrap

coroutine.create(fn) mencipta coroutine dan mengembalikan objek coroutine (jenis thread). coroutine.wrap(fn) mencipta coroutine dan mengembalikan fungsi yang, apabila dipanggil, menyambung semula coroutine tersebut. wrap lebih mudah tetapi menyembunyikan objek coroutine.

-- create: returns coroutine object
local co = coroutine.create(function(x)
  return x * 2
end)
local ok, val = coroutine.resume(co, 5)
print(ok, val)   -- true  10

-- wrap: returns a resumable function
local gen = coroutine.wrap(function(x)
  return x * 3
end)
print(gen(5))    -- 15

Kitar Hayat Coroutine

Coroutine mempunyai empat keadaan: suspended (tidak berjalan), running (sedang dilaksanakan), dead (telah dikembalikan atau mengalami ralat), dan normal (dijeda kerana menyambung semula coroutine lain). Semak keadaan dengan coroutine.status(co).

local co = coroutine.create(function()
  coroutine.yield()
end)

print(coroutine.status(co))  -- suspended
coroutine.resume(co)          -- runs until yield
print(coroutine.status(co))  -- suspended again
coroutine.resume(co)          -- runs until end
print(coroutine.status(co))  -- dead

Menjalankan Berbilang Coroutine

Cipta berbilang coroutine dan selang-selikan pelaksanaannya dengan menyambung semula setiap coroutine secara bergilir-gilir. Ini mensimulasikan pelaksanaan serentak (multitugas kooperatif). Setiap coroutine mengekalkan keadaannya sendiri antara operasi yield.

local function worker(name, steps)
  for i = 1, steps do
    print(name .. ": step " .. i)
    coroutine.yield()
  end
end

local co1 = coroutine.create(function() worker("A", 3) end)
local co2 = coroutine.create(function() worker("B", 3) end)

for _ = 1, 3 do
  coroutine.resume(co1)
  coroutine.resume(co2)
end
-- A:1, B:1, A:2, B:2, A:3, B:3

Lelaran coroutine.wrap

coroutine.wrap biasanya digunakan untuk mencipta lelar. Fungsi yang dikembalikan dipanggil setiap kali lelar bergerak ke hadapan. Apabila badan coroutine berakhir, fungsi tersebut menghasilkan ralat — gunakan pcall atau semak status jika perlu.

local function range(n)
  return coroutine.wrap(function()
    for i = 1, n do
      coroutine.yield(i)
    end
  end)
end

for v in range(5) do
  io.write(v .. " ")
end
print()  -- 1 2 3 4 5

Ralat dalam Coroutine

Jika coroutine menghasilkan ralat, coroutine.resume mengembalikan false diikuti mesej ralat. Coroutine tersebut beralih kepada keadaan dead. Coroutine yang mati tidak boleh disambung semula.

local co = coroutine.create(function(x)
  if x < 0 then error("negative input: " .. x) end
  return math.sqrt(x)
end)

local ok, val = coroutine.resume(co, -1)
print(ok, val)    -- false  input:2: negative input: -1
print(coroutine.status(co))  -- dead

-- Can't resume a dead coroutine:
ok, val = coroutine.resume(co)
print(ok, val)    -- false  cannot resume dead coroutine

Identiti Coroutine

coroutine.running() mengembalikan coroutine yang sedang berjalan dan boolean yang menunjukkan sama ada ia ialah bebenang utama. Gunakan ini di dalam coroutine untuk mendapatkan rujukan kepada coroutine itu sendiri.

local co = coroutine.create(function()
  local self, isMain = coroutine.running()
  print("type:", type(self))      -- thread
  print("isMain:", isMain)        -- false
  print("status:", coroutine.status(self)) -- running
end)

coroutine.resume(co)

-- In main thread:
local main, isMain = coroutine.running()
print("main isMain:", isMain)    -- true

Penjana Tanpa Penghujung

Badan coroutine boleh mengandungi gelung tanpa penghujung dengan operasi yield di dalamnya — penjana menghasilkan nilai apabila diminta tanpa berhenti. Ini ialah kes penggunaan utama: jujukan malas tanpa penghujung.

local function naturals(start)
  return coroutine.wrap(function()
    local n = start or 1
    while true do
      coroutine.yield(n)
      n = n + 1
    end
  end)
end

local gen = naturals(1)
for i = 1, 8 do
  io.write(gen() .. " ")
end
print()  -- 1 2 3 4 5 6 7 8

Coroutine sebagai Tugasan

Penjadual tugasan asas: simpan coroutine dalam baris gilir dan sambung semula setiap coroutine secara bergilir-gilir. Apabila coroutine melakukan yield, coroutine itu kembali ke baris gilir. Apabila coroutine mati, coroutine itu dikeluarkan. Ini ialah penjadual kooperatif minimum.

local tasks = {}

local function spawn(fn)
  tasks[#tasks+1] = coroutine.create(fn)
end

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

spawn(function() for i=1,3 do print("T1:"..i); coroutine.yield() end end)
spawn(function() for i=1,3 do print("T2:"..i); coroutine.yield() end end)
run()

Memori Coroutine

Setiap coroutine mempunyai stacknya sendiri. Stack boleh menjadi besar untuk rantaian panggilan yang mendalam. Dalam senario berprestasi tinggi, elakkan daripada mencipta beribu-ribu coroutine yang hidup serentak. Gunakan semula coroutine apabila boleh, atau gunakan pool.

-- Coroutine pool concept
local pool = {}

local function getCoroutine(fn)
  -- Reuse dead coroutine slots
  for i, co in ipairs(pool) do
    if coroutine.status(co) == "dead" then
      pool[i] = coroutine.create(fn)
      return pool[i]
    end
  end
  local co = coroutine.create(fn)
  pool[#pool+1] = co
  return co
end

print("Pool pattern for coroutine reuse")

Semakan Pantas

Apakah keadaan coroutine sejurus selepas coroutine.create(fn)?

Imbas Kembali: Mencipta Coroutine

Ringkasan:

  • coroutine.create(fn) → objek coroutine; wrap(fn) → fungsi yang boleh disambung semula
  • Keadaan: digantung → berjalan → digantung/mati
  • coroutine.resume(co, ...) memulakan/menyambung semula
  • Ralat semasa penyambungan semula: false + mesej ralat; coroutine → mati
  • Penjana tanpa penghujung melalui while true do yield() end
  • Gunakan untuk multitugas koperatif dan jujukan malas
Percuma untuk bermula

Pelajari Lua dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
40
Pelajaran
159

Soalan Lazim

Adakah pelajaran “Mencipta Coroutine” percuma?

Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Lua Academy, termasuk “Mencipta Coroutine”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Lua Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Mencipta Coroutine”?

Cipta coroutine dengan coroutine.create dan coroutine.wrap. Anda berlatih Lua Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Lua Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Lua Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.

Berapa lamakah pelajaran “Mencipta Coroutine” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Lua Academy ini?

Ya. Setiap pelajaran Lua Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Mencipta Coroutine
  2. resume dan yield
  3. Status Coroutine
  4. Corak Pengeluar-Pengguna
← Kembali ke Lua Academy