Pola Produsen-Konsumen
Implementasikan pipeline produsen-konsumen menggunakan coroutine.
Pola Produsen-Konsumen adalah pelajaran Lua Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Lua Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Lua Academy mencakup 4 pelajaran total.
Penjelasan Pola
Pola produsen-konsumen dengan korutin: produsen menghasilkan data dan melakukan yield pada setiap item; konsumen menerima item satu per satu. Keduanya tidak perlu mengetahui implementasi satu sama lain — keduanya berkomunikasi melalui yield/resume. Dengan demikian, pembuatan data terpisah dari pemrosesan data.
local function makeProducer(items)
return coroutine.create(function()
for _, item in ipairs(items) do
coroutine.yield(item)
end
end)
end
local function consume(producer)
while true do
local ok, item = coroutine.resume(producer)
if not ok or item == nil then break end
print("Processing:", item)
end
end
consume(makeProducer({10, 20, 30, 40}))Produsen Tak Terbatas
Korutin produsen dapat melakukan yield pada urutan yang tidak terbatas. Konsumen menentukan kapan harus berhenti. Pola ini sangat cocok untuk sumber data streaming: pembacaan sensor, peristiwa log, dan urutan yang dihasilkan.
local function primes()
return coroutine.wrap(function()
local function isPrime(n)
if n<2 then return false end
for i=2, math.floor(math.sqrt(n)) do
if n%i==0 then return false end
end
return true
end
local n = 2
while true do
if isPrime(n) then coroutine.yield(n) end
n = n + 1
end
end)
end
local gen = primes()
for i = 1, 10 do
io.write(gen() .. " ")
end
print() -- 2 3 5 7 11 13 17 19 23 29Konsumen sebagai Korutin
Konsumen juga dapat berupa korutin, sehingga terbentuk pasangan produsen-konsumen yang sepenuhnya simetris. Fungsi "penggerak" ketiga mengoordinasikan keduanya. Ini berguna untuk alur dengan penyangga ketika produsen dan konsumen memiliki laju yang berbeda.
local function producer()
return coroutine.create(function(consumer)
for i = 1, 5 do
coroutine.resume(consumer, i * 10)
coroutine.yield() -- wait
end
end)
end
local consumer = coroutine.create(function()
while true do
local val = coroutine.yield()
print("Received:", val)
end
end)
coroutine.resume(consumer) -- start, waits for data
local pro = producer()
for i = 1, 5 do
coroutine.resume(pro, consumer)
endTekanan Balik
Tekanan balik terjadi ketika konsumen memberi sinyal kepada produsen untuk memperlambat proses. Dengan korutin, hal ini berlangsung secara alami: produsen melakukan yield setelah setiap item dan menunggu konsumen meminta item berikutnya. Jika konsumen lambat, produsen cukup menunggu.
local function slowConsumer(gen)
for v in gen do
-- Simulate slow processing
print("Processing", v, "...")
-- In real code: os.execute("sleep 0.1")
end
end
local function fastProducer(n)
return coroutine.wrap(function()
for i = 1, n do
print("Producing", i)
coroutine.yield(i)
end
end)
end
-- Producer automatically waits for consumer:
slowConsumer(fastProducer(4))Pemrosesan Secara Kelompok
Produsen berkelompok mengumpulkan N item sebelum melakukan yield pada satu kelompok. Konsumen menerima dan memproses kelompok secara lengkap. Cara ini mengurangi beban koordinasi bagi produsen berfrekuensi tinggi.
local function batchProducer(items, batchSize)
return coroutine.wrap(function()
local batch = {}
for _, item in ipairs(items) do
batch[#batch+1] = item
if #batch >= batchSize then
coroutine.yield(batch)
batch = {}
end
end
if #batch > 0 then coroutine.yield(batch) end
end)
end
local data = {1,2,3,4,5,6,7,8,9,10}
for batch in batchProducer(data, 3) do
print("Batch:", table.concat(batch, ","))
end
-- Batch: 1,2,3
-- Batch: 4,5,6
-- Batch: 7,8,9
-- Batch: 10Produsen Baris Berkas
Baca berkas secara malas: korutin produsen membaca baris satu per satu dan melakukan yield pada setiap baris. Konsumen memproses baris tanpa memuat seluruh berkas ke memori.
local function lineProducer(path)
return coroutine.wrap(function()
local f = io.open(path, "r")
if not f then return end
for line in f:lines() do
coroutine.yield(line)
end
f:close()
end)
end
-- Process file line by line without loading all at once
local wordCount = 0
for line in lineProducer("data.txt") do
for _ in line:gmatch("%S+") do
wordCount = wordCount + 1
end
end
print("Words:", wordCount)Tahap Transformasi
Sisipkan tahap transformasi di antara produsen dan konsumen. Transformasi membaca dari satu korutin dan melakukan yield pada nilai yang telah diproses untuk korutin lain. Bangun alur data dengan merangkai tahap-tahap ini.
local function transform(source, fn)
return coroutine.wrap(function()
for v in source do
coroutine.yield(fn(v))
end
end)
end
local numbers = coroutine.wrap(function()
for i = 1, 6 do coroutine.yield(i) end
end)
local doubled = transform(numbers, function(n) return n*2 end)
local filtered = coroutine.wrap(function()
for v in doubled do
if v > 4 then coroutine.yield(v) end
end
end)
for v in filtered do io.write(v.." ") end
print() -- 6 8 10 12Penerusan Kesalahan dalam Alur
Kesalahan dalam alur korutin diteruskan melalui keadaan mati atau melalui pcall. Bungkus tahap-tahap alur dalam pcall untuk menangkap dan menangani kesalahan dengan baik tanpa membuat seluruh alur berhenti.
local function safeStage(source, fn)
return coroutine.wrap(function()
for v in source do
local ok, result = pcall(fn, v)
if ok then
coroutine.yield(result)
else
print("Error processing", v, ":", result)
end
end
end)
end
local data = coroutine.wrap(function()
for _, v in ipairs({4, -1, 9, 0, 16}) do coroutine.yield(v) end
end)
local results = safeStage(data, function(n)
assert(n > 0, "non-positive")
return math.sqrt(n)
end)
for v in results do print(v) endMenggabungkan Produsen
Gabungkan beberapa produsen menjadi satu: lakukan pembagian giliran di antara semua produsen yang masih aktif, lalu keluarkan setiap item secara bergantian. Berhenti ketika semua produsen telah kehabisan item.
local function merge(...)
local producers = {...}
return coroutine.wrap(function()
while #producers > 0 do
local alive = {}
for _, co in ipairs(producers) do
local ok, v = coroutine.resume(co)
if ok and v ~= nil then
coroutine.yield(v)
alive[#alive+1] = co
end
end
producers = alive
end
end)
end
local function src(items)
return coroutine.create(function()
for _,v in ipairs(items) do coroutine.yield(v) end
end)
end
for v in merge(src({1,3,5}),src({2,4,6})) do
io.write(v.." ")
end
print() -- 1 2 3 4 5 6Kasus Penggunaan di Dunia Nyata
Alur pemrosesan log: produsen membaca baris log, tahap penyaring hanya mempertahankan baris kesalahan, tahap transformasi mengambil informasi penting, dan konsumen mengelompokkan berdasarkan jenis kesalahan. Setiap tahap merupakan korutin mandiri yang dapat diuji.
local function makeFilter(src, pred)
return coroutine.wrap(function()
for line in src do
if pred(line) then coroutine.yield(line) end
end
end)
end
local logs = coroutine.wrap(function()
local entries = {
"INFO: started",
"ERROR: timeout",
"DEBUG: connecting",
"ERROR: auth failed",
}
for _, e in ipairs(entries) do coroutine.yield(e) end
end)
local errors = makeFilter(logs, function(l) return l:match("^ERROR") end)
for line in errors do print(line) end
-- ERROR: timeout
-- ERROR: auth failedPemeriksaan Singkat
Bagaimana pola korutin produsen-konsumen menangani tekanan balik?
Ringkasan: Produsen-Konsumen
Ringkasan:
- Produsen melakukan yield pada item; konsumen menggerakkan proses dengan memanggil resume
- Produsen tak terbatas:
while true do yield() end - Alur: rangkai korutin transformasi di antara produsen dan konsumen
- Tekanan balik berlangsung otomatis: produsen menunggu konsumen
- Gunakan tahap pengelompokan, penyaringan, dan penggabungan sebagai pembungkus korutin
- Gunakan pcall pada tahap alur untuk mengisolasi kesalahan
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Pola Produsen-Konsumen” gratis?
Ya — teks lengkap “Pola Produsen-Konsumen” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Lua Academy, upgrade ke CoddyKit PRO. Kursus Lua Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Pola Produsen-Konsumen”?
Implementasikan pipeline produsen-konsumen menggunakan coroutine. Kamu berlatih Lua Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Lua Academy?
Tidak diperlukan pengalaman sebelumnya. Lua Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.
Berapa lama pelajaran “Pola Produsen-Konsumen” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Lua Academy ini?
Ya. Setiap pelajaran Lua Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Membuat Coroutine
- resume dan yield
- Status Coroutine
- Pola Produsen-Konsumen