0Pricing
Lua Academy · Ders

Üretici-Tüketici Örüntüsü

Coroutine'leri kullanarak bir üretici-tüketici veri akışı uygulayın.

Üretici-Tüketici Örüntüsü, CoddyKit'te ücretsiz bir Lua Academy dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Lua Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Lua Academy kursu toplamda 4 dersten oluşur.

Kalıbın Açıklaması

Coroutine'lerle üretici-tüketici kalıbı: üretici veri oluşturur ve her öğeyi yield eder; tüketici öğeleri birer birer alır. İkisinin de diğerinin uygulamasını bilmesi gerekmez; yield/resume aracılığıyla iletişim kurarlar. Böylece veri oluşturma ile veri işleme birbirinden ayrılır.

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}))

Sonsuz Üretici

Bir üretici coroutine sonsuz bir dizi yield edebilir. Ne zaman durulacağını tüketici belirler. Bu, veri akışı sağlayan kaynaklar için idealdir: sensör okumaları, günlük olayları ve oluşturulan diziler.

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 29

Coroutine Olarak Tüketici

Tüketici de bir coroutine olabilir; böylece tamamen simetrik bir üretici-tüketici çifti oluşturulur. Üçüncü bir "sürücü" işlevi her ikisini düzenler. Bu, üretici ve tüketicinin farklı hızlarda çalıştığı arabelleğe alınmış işlem hatları için kullanışlıdır.

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)
end

Geri Basınç

Geri basınç, tüketicinin üreticiye yavaşlaması gerektiğini bildirmesidir. Coroutine'lerle bu doğal biçimde gerçekleşir: üretici her öğeden sonra yield eder ve tüketicinin bir sonrakini istemesini bekler. Tüketici yavaşsa üretici basitçe bekler.

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))

Toplu İşleme

Toplu üretici, bir batch yield etmeden önce N öğe toplar. Tüketici tam batch'leri alır ve işler. Bu, yüksek sıklıkta çalışan üreticiler için eşgüdüm yükünü azaltır.

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: 10

Dosya Satırı Üreticisi

Bir dosyayı tembel biçimde okuyun: üretici coroutine satırları birer birer okur ve her birini yield eder. Tüketici, dosyanın tamamını belleğe yüklemeden satırları işler.

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)

Dönüştürme Aşaması

Üretici ile tüketici arasına bir dönüştürme aşaması ekleyin. Dönüştürme aşaması bir coroutine'den okur ve işlenmiş değerleri başka bir coroutine'e yield eder. Bu aşamaları zincirleyerek veri işlem hatları oluşturun.

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 12

İşlem Hatlarında Hata Yayılımı

Coroutine işlem hatalarındaki hatalar, ölü durum veya pcall aracılığıyla yayılır. Tüm işlem hattının çökmesini önleyerek hataları düzgün biçimde yakalayıp işlemek için işlem hattı aşamalarını pcall ile sarmalayın.

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) end

Üreticileri Birleştirme

Birden çok üreticiyi tek bir üreticide birleştirin: etkin üreticiler arasında dönüşümlü ilerleyerek her seferinde bir öğe yield edin. Tüm üreticiler tükendiğinde durun.

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 6

Gerçek Dünya Kullanım Örneği

Günlük işleme işlem hattı: üretici günlük satırlarını okur, filtre aşaması yalnızca hata satırlarını tutar, dönüştürme aşaması önemli bilgileri çıkarır, tüketici de hata türüne göre toplulaştırır. Her aşama bağımsız ve test edilebilir bir coroutine'dir.

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 failed

Hızlı Kontrol

Üretici-tüketici coroutine kalıbı geri basıncı nasıl ele alır?

Özet: Üretici-Tüketici

Özet:

  • Üretici öğeleri yield eder; tüketici resume çağırarak süreci yönlendirir
  • Sonsuz üreticiler: while true do yield() end
  • İşlem hatları: üretici ile tüketici arasına dönüştürme coroutine'leri zincirleyin
  • Geri basınç otomatiktir: üretici tüketiciyi bekler
  • Coroutine sarmalayıcıları olarak toplu işleme, filtre ve birleştirme aşamaları kullanın
  • Hataları aşamalara yalıtmak için işlem hattı aşamalarında pcall kullanın

Sıkça Sorulan Sorular

“Üretici-Tüketici Örüntüsü” dersi ücretsiz mi?

Evet — “Üretici-Tüketici Örüntüsü” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Lua Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Lua Academy kursu toplamda 4 dersten oluşur.

“Üretici-Tüketici Örüntüsü” dersinde ne öğreneceğim?

Coroutine'leri kullanarak bir üretici-tüketici veri akışı uygulayın. Lua Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

Lua Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te Lua Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.

“Üretici-Tüketici Örüntüsü” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu Lua Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her Lua Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. Coroutine Oluşturma
  2. resume ve yield
  3. Coroutine Durumu
  4. Üretici-Tüketici Örüntüsü
← Lua Academy Sayfasına Dön