我使用coroutine来实现生产者-消费者模型。我的代码如下:
function send(prod, x)
coroutine.resume(prod, x)
end
function receive()
local x = coroutine.yield()
return x
end
function consumer()
return coroutine.create(function ()
while true do
local x = receive()
io.write(x, "\n")
end
end)
end
function producer(prod)
while true do
local x = io.read()
send(prod, x)
end
end
producer(consumer())当我运行这段代码时,我得到:

第一个输入消息(“Hello”)消失了。它应该印两次,但现在只印一次。在我看来,我的生产者-消费者模式的流程图应该如下所示:

我搞错了吗?
发布于 2020-10-06 12:29:44
输入第一个字符串后,按以下顺序调用函数:
send,consumer,receive,producer.返回的coroutine然后,该程序等待用户输入.local x = coroutine.yield()和local x = receive()向producer屈服。目前还没有达到io.write(x, "\n")。
用户输入第二行后,如下所示:
send,consumer在local x = receive()之后恢复并打印第二个输入,consumer调用receive,producer生成producer,G 236
以下是更正确的代码:
local function send (x)
coroutine.yield(x)
end
local function receive (prod)
local status, value = coroutine.resume(prod)
return value
end
local function producer()
return coroutine.create(
function ()
while true do
local x = io.read() -- produce new value
send(x)
end
end
)
end
function consumer (prod)
while true do
local x = receive(prod) -- get new value
io.write(x, "\n") -- consume new value
end
end
consumer(producer())请注意,这是consumer(producer()),而不是相反。还请注意,producer是协同线,而不是consumer。此外,send收益和receive恢复。
consumer开始节目,一遍又一遍地恢复producer。如果相反,如您的示例所示,consumer直到第二次迭代才准备使用该产品。
UPD:在这里遵循“强制喂食”,即生产者驱动的代码:
local function send (cons, x)
coroutine.resume (cons, x)
end
local function receive ()
return coroutine.yield()
end
local function consumer()
return coroutine.create (
function (x)
while true do
io.write(x, '\n')
-- corotine.yield() returns the extra arguments of coroutine.resume()
x = receive()
end
end
)
end
function producer (cons)
while true do
local x = io.read() -- make a new value
send (cons, x) -- feed the new value
end
end
producer (consumer ())与作者的示例不同的是,producer send是consumer,receive则是write。
发布于 2020-10-07 07:58:25
第一次“恢复”协同值时,它不会直接跳转到第一个yield,而是使用给定的参数调用包装函数:
local co = coroutine.wrap(function(aaa)
print(aaa) -- prints "first"
print(coroutine.yield()) -- prints "second"
end)
co("first")
co("second")在您的代码中解决这个问题的简单方法是:
local send, receive =
coroutine.resume, coroutine.yield
function consumer()
return coroutine.create(function(x)
while true do
io.write(x, "\n")
x = receive()
end
end)
end
function producer(consumer)
while true do
local x = io.read()
send(consumer, x)
end
end
producer(consumer())https://stackoverflow.com/questions/64225003
复制相似问题