概述
Lua通过协程可以优雅地实现生产者-消费者模型,利用协程的协作式并发特性来完成数据生产与消费的解耦
生产者-消费者模型是一种经典的并发设计模式,通过一个缓冲区(交易场所)来解耦生产者和消费者之间的强依赖关系
在Lua中,协程(coroutine)为实现这种模式提供了天然的支持,因为协程可以在执行过程中暂停并在之后继续执行,非常适合模拟生产与消费的协作过程
模型核心概念
1 ) 三大角色
- 生产者:生成数据的协程(如数据采集模块)
- 消费者:处理数据的协程(如数据分析模块)
- 缓冲区:共享的阻塞队列(解耦生产与消费速度差异)
2 ) 生产者-消费者模型遵循3-2-1原则:
- 3种关系:生产者-生产者(互斥)、消费者-消费者(互斥)、生产者-消费者(同步与互斥)
- 2种角色:生产者(数据生成方)、消费者(数据处理方)
- 1个交易场所:缓冲区(解耦媒介)
在Lua中,生产者负责生成数据并放入缓冲区,消费者从缓冲区取出数据进行处理,两者通过协程协作实现异步处理
2 ) 两种关系
- 同步:缓冲区空时消费者等待生产,满时生产者等待消费
- 互斥:同一时刻仅一个协程操作缓冲区
Lua协程的核心API包括
coroutine.create(func)- 创建协程coroutine.resume(co, ...)- 恢复协程执行coroutine.yield(...)- 挂起协程并返回控制权
--- 协程基础示例
function coFunc()
print("协程开始执行")
coroutine.yield("中断执行")
print("协程恢复执行")
end
co = coroutine.create(coFunc)
print(coroutine.resume(co)) -- 输出: true 中断执行
print(coroutine.resume(co)) -- 输出: true 协程恢复执行
--[[
协程开始执行
true 中断执行
协程恢复执行
true
]]
Lua协程关键技术
基本语法
--- 创建协程
local producer_co = coroutine.create(function() ... end)
--- 挂起协程(让出执行权)
coroutine.yield(data)
--- 恢复协程执行
coroutine.resume(producer_co)
示例
--- 创建协程
local producer_co = coroutine.create(function()
-- 这里是协程的实际代码
print("协程开始执行")
local data = "生产的数据"
coroutine.yield(data) -- 挂起协程并返回数据
print("协程恢复执行")
end)
--- 恢复协程执行
local success, result = coroutine.resume(producer_co)
if success then
print("协程返回的数据:", result)
end
--[[
协程开始执行
协程返回的数据: 生产的数据
]]
协程相关函数总结
| 函数 | 功能 | 特点 |
|---|---|---|
coroutine.create(f) | 创建协程 | 返回thread对象,初始状态为suspended |
coroutine.resume(co, ...) | 启动/恢复协程 | 在保护模式下执行,返回执行状态和结果 |
coroutine.yield(...) | 挂起协程 | 将参数传递给resume |
coroutine.status(co) | 查看状态 | 返回suspended/running/dead/normal |
coroutine.wrap(f) | 创建包装协程 | 返回函数而非thread对象,错误会直接抛出 |
1 ) 特点:
- 非抢占式协作调度,避免锁竞争
- 状态保存:
yield暂停时保留局部变量状态
2 ) 基础实现
使用协程实现简单的生产者-消费者
-- 创建缓冲区
local buffer = {}
local buffer_size = 3
-- 生产者协程
function producer()
for i = 1, 10 do
-- 缓冲区满时挂起
while #buffer >= buffer_size do
print("缓冲区满,生产者等待...")
coroutine.yield()
end
table.insert(buffer, i)
print("[生产] 产品: " .. i .. "\t缓冲区: [" .. table.concat(buffer, ",") .. "]")
coroutine.yield() -- 关键:生产后主动让出执行权
end
print("生产者完成所有任务")
end
-- 消费者协程
function consumer()
for i = 1, 10 do
-- 缓冲区空时挂起
while #buffer == 0 do
print("缓冲区空,消费者等待...")
coroutine.yield()
end
local item = table.remove(buffer, 1)
print("[消费] 产品: " .. item .. "\t缓冲区: [" .. table.concat(buffer, ",") .. "]")
coroutine.yield() -- 关键:消费后主动让出执行权
end
print("消费者完成所有任务")
end
-- 创建协程对象
local co_producer = coroutine.create(producer)
local co_consumer = coroutine.create(consumer)
-- 协程调度器 (核心修复)
local active = true
while active do
-- 交替唤醒生产者和消费者
local r1 = coroutine.resume(co_producer)
local r2 = coroutine.resume(co_consumer)
-- 检查协程状态
local s1 = coroutine.status(co_producer)
local s2 = coroutine.status(co_consumer)
-- 当两者都完成时退出循环
if s1 == "dead" and s2 == "dead" then
active = false
print("所有任务完成,最终缓冲区: [" .. table.concat(buffer, ",") .. "]")
end
end
--[[
[生产] 产品: 1 缓冲区: [1]
[消费] 产品: 1 缓冲区: []
[生产] 产品: 2 缓冲区: [2]
[消费] 产品: 2 缓冲区: []
[生产] 产品: 3 缓冲区: [3]
[消费] 产品: 3 缓冲区: []
[生产] 产品: 4 缓冲区: [4]
[消费] 产品: 4 缓冲区: []
[生产] 产品: 5 缓冲区: [5]
[消费] 产品: 5 缓冲区: []
[生产] 产品: 6 缓冲区: [6]
[消费] 产品: 6 缓冲区: []
[生产] 产品: 7 缓冲区: [7]
[消费] 产品: 7 缓冲区: []
[生产] 产品: 8 缓冲区: [8]
[消费] 产品: 8 缓冲区: []
[生产] 产品: 9 缓冲区: [9]
[消费] 产品: 9 缓冲区: []
[生产] 产品: 10 缓冲区: [10]
[消费] 产品: 10 缓冲区: []
生产者完成所有任务
消费者完成所有任务
所有任务完成,最终缓冲区: []
]]
3 ) 缓冲区控制
实现有界缓冲区控制
--- 缓冲区管理
local Buffer = {}
Buffer.__index = Buffer
function Buffer:new(size)
local obj = {
data = {},
max_size = size or 10
}
setmetatable(obj, Buffer)
return obj
end
function Buffer:put(item)
if #self.data < self.max_size then
table.insert(self.data, item)
return true
end
return false
end
function Buffer:get()
if #self.data > 0 then
return table.remove(self.data, 1)
end
return nil
end
function Buffer:is_full()
return #self.data >= self.max_size
end
function Buffer:is_empty()
return #self.data == 0
end
-- 创建缓冲区实例(容量=3)
local buf = Buffer:new(3)
print("=== 初始状态 ===")
print("缓冲区是否为空:", buf:is_empty()) -- true
print("缓冲区是否为满:", buf:is_full()) -- false
print("当前元素数量:", #buf.data) -- 0
print()
-- 添加元素
print("添加 A:", buf:put("A")) -- true
print("添加 B:", buf:put("B")) -- true
print("添加 C:", buf:put("C")) -- true
print("添加 D (超过容量):", buf:put("D")) -- false (添加失败)
print("当前元素数量:", #buf.data) -- 3
print("缓冲区是否为满:", buf:is_full()) -- true
print()
-- 取出元素
print("取出元素:", buf:get()) -- A
print("取出元素:", buf:get()) -- B
print("当前元素数量:", #buf.data) -- 1
print("缓冲区是否为空:", buf:is_empty()) -- false
print()
-- 清空缓冲区
print("取出最后元素:", buf:get()) -- C
print("尝试空取出:", buf:get()) -- nil
print("缓冲区是否为空:", buf:is_empty()) -- true
--[[
=== 初始状态 ===
缓冲区是否为空: true
缓冲区是否为满: false
当前元素数量: 0
添加 A: true
添加 B: true
添加 C: true
添加 D (超过容量): false
当前元素数量: 3
缓冲区是否为满: true
取出元素: A
取出元素: B
当前元素数量: 1
缓冲区是否为空: false
取出最后元素: C
尝试空取出: nil
缓冲区是否为空: true
]]
完整代码实现
1 ) 环形缓冲区(BlockingQueue)
local BlockingQueue = {}
function BlockingQueue.new(size)
return {
buffer = {},
capacity = size,
count = 0,
head = 1,
tail = 1
}
end
--- 生产者调用:缓冲区满时挂起
function BlockingQueue:push(item)
while self.count >= self.capacity do
coroutine.yield("FULL") -- 挂起生产者
end
self.buffer[self.tail] = item
self.tail = (self.tail % self.capacity) + 1
self.count = self.count + 1
end
--- 消费者调用:缓冲区空时挂起
function BlockingQueue:pop()
while self.count <= 0 do
coroutine.yield("EMPTY") -- 挂起消费者
end
local item = self.buffer[self.head]
self.head = (self.head % self.capacity) + 1
self.count = self.count - 1
return item
end
2 ) 生产者协程(每秒生成1个数据)
local function producer(queue)
local id = 1
while true do
local data = "Product-"..id
queue:push(data)
print("[Producer] Generated: "..data)
id = id + 1
os.execute("sleep 1") -- 模拟生产延迟
end
end
3 ) 消费者协程(每秒消费2个数据)
local function consumer(queue)
while true do
local data = queue:pop()
print("[Consumer] Processed: "..data)
os.execute("sleep 0.5") -- 模拟处理耗时
end
end
4 ) 主调度器(驱动协程协作)
local function main()
local queue = BlockingQueue.new(5) -- 容量为5的缓冲区
--- 创建协程
local p_co = coroutine.create(producer)
local c_co = coroutine.create(consumer)
--- 循环恢复协程执行
while true do
coroutine.resume(p_co, queue)
coroutine.resume(c_co, queue)
end
end
main()
5 ) 完整代码如下
-- 阻塞队列实现(保持不变)
local BlockingQueue = {}
BlockingQueue.__index = BlockingQueue
function BlockingQueue.new(size)
local q = {
buffer = {},
capacity = size,
count = 0,
head = 1,
tail = 1,
waiting_producers = {}, -- 等待的生产者队列
waiting_consumers = {} -- 等待的消费者队列
}
setmetatable(q, BlockingQueue)
return q
end
function BlockingQueue:push(item)
while self.count >= self.capacity do
table.insert(self.waiting_producers, coroutine.running())
coroutine.yield("FULL")
end
self.buffer[self.tail] = item
self.tail = (self.tail % self.capacity) + 1
self.count = self.count + 1
if #self.waiting_consumers > 0 then
coroutine.resume(table.remove(self.waiting_consumers, 1))
end
end
function BlockingQueue:pop()
while self.count <= 0 do
table.insert(self.waiting_consumers, coroutine.running())
coroutine.yield("EMPTY")
end
local item = self.buffer[self.head]
self.buffer[self.head] = nil
self.head = (self.head % self.capacity) + 1
self.count = self.count - 1
if #self.waiting_producers > 0 then
coroutine.resume(table.remove(self.waiting_producers, 1))
end
return item
end
-- 修改后的生产者(带退出条件)
local function producer(queue, max_items)
for id = 1, max_items do
local data = "Product-"..id
queue:push(data)
print("[Producer] Generated: "..data)
os.execute("sleep 1")
end
print("[Producer] Completed production")
end
-- 修改后的消费者(带空值检测)
local function consumer(queue)
while true do
local data = queue:pop()
if not data then
print("[Consumer] Queue empty, exiting")
break
end
print("[Consumer] Processed: "..data)
os.execute("sleep 0.5")
end
end
-- 修复后的主函数
local function main()
local queue = BlockingQueue.new(5)
local max_produce = 10 -- 生产上限
-- 创建协程
local p_co = coroutine.create(function()
producer(queue, max_produce)
end)
local c_co = coroutine.create(function()
consumer(queue)
end)
-- 启动协程
coroutine.resume(p_co)
coroutine.resume(c_co)
-- 等待协程完成
while coroutine.status(p_co) ~= "dead" or
coroutine.status(c_co) ~= "dead" do
os.execute("sleep 0.1")
end
print("All coroutines completed")
end
-- 启动程序
main()
运行效果与关键机制
[Producer] Generated: Product-1
[Producer] Generated: Product-2
[Producer] Generated: Product-3
[Producer] Generated: Product-4
[Producer] Generated: Product-5
[Consumer] Processed: Product-1
[Consumer] Processed: Product-2
[Consumer] Processed: Product-3
[Consumer] Processed: Product-4
[Consumer] Processed: Product-5
All coroutines completed
动态平衡原理:
- 当缓冲区满时,push() 中的 yield(“FULL”) 挂起生产者
- 当消费者取走数据后,主循环通过 resume() 唤醒生产者继续工作
工程示例
1 ) 方案1
包含调度器的完整实现
-- 缓冲区类实现
Buffer = {}
Buffer.__index = Buffer
function Buffer:new(capacity)
local obj = {
data = {},
head = 1, -- 读取位置
tail = 1, -- 写入位置
count = 0, -- 当前元素数量
capacity = capacity or 5 -- 默认容量5
}
setmetatable(obj, Buffer)
return obj
end
function Buffer:is_full()
return self.count >= self.capacity
end
function Buffer:is_empty()
return self.count == 0
end
function Buffer:put(item)
if self:is_full() then
return false
end
self.data[self.tail] = item
self.tail = (self.tail % self.capacity) + 1 -- 循环缓冲区
self.count = self.count + 1
return true
end
function Buffer:get()
if self:is_empty() then
return nil
end
local item = self.data[self.head]
self.data[self.head] = nil -- 清除引用
self.head = (self.head % self.capacity) + 1 -- 循环缓冲区
self.count = self.count - 1
return item
end
-- 创建容量为3的缓冲区
local buffer = Buffer:new(3)
-- 生产者协程
local producer_co = coroutine.create(function()
for i = 1, 20 do
while buffer:is_full() do
print("缓冲区已满,生产者等待...")
coroutine.yield()
end
buffer:put(i)
print("生产者生产: " .. i)
coroutine.yield() -- 让出控制权
end
print("生产者完成工作")
end)
-- 消费者协程
local consumer_co = coroutine.create(function()
for i = 1, 20 do
while buffer:is_empty() do
print("缓冲区为空,消费者等待...")
coroutine.yield()
end
local item = buffer:get()
print("消费者消费: " .. item)
coroutine.yield() -- 让出控制权
end
print("消费者完成工作")
end)
-- 协程调度器
local function scheduler()
local producers = {producer_co} -- 修正:直接存储协程对象
local consumers = {consumer_co} -- 非表嵌套
while true do
local all_done = true
-- 调度生产者
for _, co in ipairs(producers) do
if coroutine.status(co) ~= "dead" then
local success, err = coroutine.resume(co)
if not success then
print("生产者协程错误: " .. tostring(err))
end
all_done = false
end
end
-- 调度消费者
for _, co in ipairs(consumers) do
if coroutine.status(co) ~= "dead" then
local success, err = coroutine.resume(co)
if not success then
print("消费者协程错误: " .. tostring(err))
end
all_done = false
end
end
if all_done then
break
end
end
end
-- 启动调度器
scheduler()
--[[
生产者生产: 1
消费者消费: 1
生产者生产: 2
消费者消费: 2
生产者生产: 3
消费者消费: 3
生产者生产: 4
消费者消费: 4
生产者生产: 5
消费者消费: 5
生产者生产: 6
消费者消费: 6
生产者生产: 7
消费者消费: 7
生产者生产: 8
消费者消费: 8
生产者生产: 9
消费者消费: 9
生产者生产: 10
消费者消费: 10
生产者生产: 11
消费者消费: 11
生产者生产: 12
消费者消费: 12
生产者生产: 13
消费者消费: 13
生产者生产: 14
消费者消费: 14
生产者生产: 15
消费者消费: 15
生产者生产: 16
消费者消费: 16
生产者生产: 17
消费者消费: 17
生产者生产: 18
消费者消费: 18
生产者生产: 19
消费者消费: 19
生产者生产: 20
消费者消费: 20
生产者完成工作
消费者完成工作
]]
2 ) 方案2
--- 生产者-消费者模型基础实现
local buffer = {}
local buffer_size = 3 -- 缓冲区大小
--- 生产者协程
function producer()
for i = 1, 10 do
--- 等待缓冲区有空位
while #buffer >= buffer_size do
coroutine.yield() -- 暂停,等待消费者消费
end
--- 生产数据
table.insert(buffer, i)
print("生产者生产: " .. i)
--- 通知消费者
coroutine.yield()
end
print("生产者结束")
end
--- 消费者协程
function consumer()
while true do
--- 等待缓冲区有数据
while #buffer == 0 do
coroutine.yield() -- 暂停,等待生产者生产
end
--- 消费数据
local data = table.remove(buffer, 1)
print("消费者消费: " .. data)
--- 通知生产者
coroutine.yield()
end
end
--- 协程调度器
function scheduler()
-- 修正1:统一变量命名(原变量名存在下划线不一致问题)
local producer_co = coroutine.create(producer)
local consumer_co = coroutine.create(consumer)
local producer_done = false -- 新增生产者完成标志
while true do
--- 恢复生产者(仅当未完成时)
if not producer_done then
-- 修正2:修复变量名拼写错误(原为producerco)
local status, msg = coroutine.resume(producer_co)
if not status then -- 协程执行出错
print("生产者错误: " .. tostring(msg))
break
elseif coroutine.status(producer_co) == "dead" then
producer_done = true -- 标记生产者完成
print("生产者协程结束")
end
end
--- 恢复消费者
-- 修正3:修复变量名拼写错误(原为consumerco)
local status, msg = coroutine.resume(consumer_co)
if not status then
print("消费者错误: " .. tostring(msg))
break
end
--- 修正4:完善结束条件(生产者完成且缓冲区为空)
if producer_done and #buffer == 0 then
print("所有任务完成")
break
end
end
end
--- 启动调度器
scheduler()
--[[
生产者生产: 1
消费者消费: 1
生产者生产: 2
消费者消费: 2
生产者生产: 3
消费者消费: 3
生产者生产: 4
消费者消费: 4
生产者生产: 5
消费者消费: 5
生产者生产: 6
消费者消费: 6
生产者生产: 7
消费者消费: 7
生产者生产: 8
消费者消费: 8
生产者生产: 9
消费者消费: 9
生产者生产: 10
消费者消费: 10
生产者结束
生产者协程结束
所有任务完成
]]
3 ) 方案3
增强版本实现(支持多生产者多消费者)
local Buffer = {}
Buffer.__index = Buffer -- 修复元表设置
function Buffer:new(size)
local obj = {
data = {}, -- 直接初始化空数组
size = size or 5,
producers = {},
consumers = {}
}
setmetatable(obj, Buffer)
return obj
end
function Buffer:isFull()
return #self.data >= self.size
end
function Buffer:isEmpty()
return #self.data == 0
end
function Buffer:produce(item, id) -- 添加生产者ID参数
while self:isFull() do
coroutine.yield("buffer_full")
end
table.insert(self.data, item)
print(string.format("生产者%d生产: %d", id, item)) -- 使用传入的ID
end
function Buffer:consume(id) -- 添加消费者ID参数
while self:isEmpty() do
coroutine.yield("buffer_empty")
end
local item = table.remove(self.data, 1)
print(string.format("消费者%d消费: %d", id, item)) -- 使用传入的ID
return item
end
--- 生产者函数
function createProducer(buffer, id, count)
return coroutine.create(function()
for i = 1, count do
local item = id * 100 + i
buffer:produce(item, id) -- 传递ID
end
print("生产者"..id.."结束")
end)
end
--- 消费者函数(添加结束条件)
function createConsumer(buffer, id, total_items)
return coroutine.create(function()
local consumed = 0
while consumed < total_items do -- 限制消费总数
buffer:consume(id) -- 传递ID
consumed = consumed + 1
end
print("消费者"..id.."结束")
end)
end
--- 增强版调度器
function enhancedScheduler()
local buffer = Buffer:new(5)
local coroutines = {}
local total_items = 10 -- 总生产量(2生产者*5)
-- 创建2个生产者
table.insert(coroutines, createProducer(buffer, 1, 5))
table.insert(coroutines, createProducer(buffer, 2, 5))
-- 创建2个消费者(传入总消费量)
table.insert(coroutines, createConsumer(buffer, 1, total_items/2))
table.insert(coroutines, createConsumer(buffer, 2, total_items/2))
-- 优化调度:记录活跃协程数
local active = #coroutines
while active > 0 do
active = 0
for i, co in ipairs(coroutines) do
if coroutine.status(co) ~= "dead" then
active = active + 1
local success, msg = coroutine.resume(co)
-- 可选:添加缓冲区状态判断减少空转
-- if msg == "buffer_empty" or msg == "buffer_full" then
-- -- 可在此添加休眠逻辑
-- end
end
end
end
end
--- 启动增强版调度器
enhancedScheduler()
--[[
生产者1生产: 101
生产者1生产: 102
生产者1生产: 103
生产者1生产: 104
生产者1生产: 105
生产者1结束
消费者1消费: 101
消费者1消费: 102
消费者1消费: 103
消费者1消费: 104
消费者1消费: 105
消费者1结束
生产者2生产: 201
生产者2生产: 202
生产者2生产: 203
生产者2生产: 204
生产者2生产: 205
生产者2结束
消费者2消费: 201
消费者2消费: 202
消费者2消费: 203
消费者2消费: 204
消费者2消费: 205
消费者2结束
]]
进阶优化与最佳实践
1 ) 错误处理机制
--- 带错误处理的版本
function safeProducer(buffer, id, count)
return coroutine.create(function()
for i = 1, count do
local success, err = pcall(function()
local item = id * 100 + i
buffer:produce(item)
end)
if not success then
print("生产者错误: " .. err)
break
end
end
end)
end
完整示例
local buffer = {
max_size = 5,
queue = {},
count = 0,
head = 1,
tail = 1
}
-- 全局生产者存活计数器
local activeProducers = 0
-- 缓冲区生产方法
function buffer:produce(item)
if self.count >= self.max_size then
return false
end
self.queue[self.tail] = item
self.tail = (self.tail % self.max_size) + 1
self.count = self.count + 1
return true
end
-- 缓冲区消费方法
function buffer:consume()
if self.count <= 0 then
return nil
end
local item = self.queue[self.head]
self.queue[self.head] = nil
self.head = (self.head % self.max_size) + 1
self.count = self.count - 1
return item
end
-- 带错误处理的生产者
function safeProducer(buffer, id, count)
return coroutine.create(function()
activeProducers = activeProducers + 1 -- 注册生产者
for i = 1, count do
local success, err = pcall(function()
-- 模拟错误:生产第3个物品时触发
if i == 3 then
error("生产过程中出现意外错误!")
end
local item = id * 100 + i
while not buffer:produce(item) do
print(string.format("生产者 %d: 缓冲区已满,等待中...", id))
coroutine.yield()
end
print(string.format("生产者 %d: 成功生产 %d", id, item))
end)
if not success then
print("生产者错误: " .. err)
break
end
coroutine.yield()
end
activeProducers = activeProducers - 1 -- 注销生产者
print(string.format("生产者 %d 退出生产", id))
end)
end
-- 修复的消费者(增加生产者存活检查)
function safeConsumer(buffer, id, count)
return coroutine.create(function()
local consumed = 0
while consumed < count do
local success, err = pcall(function()
-- 模拟错误:消费第5个物品时触发
if consumed == 4 then
error("消费过程中出现数据异常!")
end
local item = buffer:consume()
if item then
consumed = consumed + 1
print(string.format("消费者 %d: 成功消费 %d", id, item))
else
-- 关键修复:当缓冲区空且无存活生产者时主动退出
if activeProducers == 0 then
error("所有生产者已退出,终止消费等待")
end
print(string.format("消费者 %d: 缓冲区为空,等待中...", id))
coroutine.yield()
end
end)
if not success then
print("消费者错误: " .. err)
break
end
coroutine.yield()
end
print(string.format("消费者 %d 完成消费任务", id))
end)
end
-- 主程序
activeProducers = 0 -- 初始化计数器
local producer1 = safeProducer(buffer, 1, 10)
local consumer1 = safeConsumer(buffer, 1, 8)
local consumer2 = safeConsumer(buffer, 2, 5)
-- 协程调度器
local function scheduler()
while true do
local anyActive = false
-- 检查生产者
if coroutine.status(producer1) == "suspended" then
anyActive = true
coroutine.resume(producer1)
end
-- 检查消费者
if coroutine.status(consumer1) == "suspended" then
anyActive = true
coroutine.resume(consumer1)
end
if coroutine.status(consumer2) == "suspended" then
anyActive = true
coroutine.resume(consumer2)
end
-- 无活跃协程时退出循环
if not anyActive then break end
end
print("所有任务完成!")
end
-- 启动调度器
scheduler()
--[[
生产者 1: 成功生产 101
消费者 1: 成功消费 101
消费者 2: 缓冲区为空,等待中...
生产者 1: 成功生产 102
消费者 1: 成功消费 102
生产者错误: 912.lua:44: 生产过程中出现意外错误!
生产者 1 退出生产
消费者错误: 912.lua:85: 所有生产者已退出,终止消费等待
消费者 1 完成消费任务
消费者错误: 912.lua:85: 所有生产者已退出,终止消费等待
消费者 2 完成消费任务
所有任务完成!
]]
2 ) 性能优化技巧
- 批量处理:支持生产者批量生产数据,减少协程切换次数
- 动态调整:根据缓冲区状态动态调整生产/消费速率
- 超时机制:为等待操作添加超时,避免无限等待
3 ) 实际应用场景
- 游戏开发:角色AI行为控制,每个角色作为独立协程[17]
- 数据处理管道:分阶段处理数据流
- 异步任务管理:管理异步操作的执行顺序
扩展应用场景
-
网络请求批处理
生产者:接收HTTP请求并存入队列
消费者:批量处理请求减少I/O开销 -
游戏逻辑更新
生产者:收集玩家操作事件
消费者:统一计算游戏状态[29] -
日志系统
生产者:多个服务生成日志
消费者:异步写入磁盘文件[5]
结论
通过Lua协程实现生产者-消费者模型具有以下优势:
- 轻量级:协程比线程更轻量,开销小
- 易控制:协作式调度,逻辑清晰
- 解耦合:生产者和消费者无需直接交互,降低系统复杂度
580



被折叠的 条评论
为什么被折叠?



