Lua 中废弃 coroutine 发生了什么?

我想知道在这个例子中 coroutine 会发生什么情况:

function powersOfTwo(i)
    coroutine.yield(i)
    powersOfTwo(2*i)
end

function iterator()
    return coroutine.wrap(function () powersOfTwo(1) end)
end

for power in iterator() do
    print(power)
    if power > 1000 then break end
end

coroutine 没有完成其代码。它是否被垃圾回收?

原文链接 https://stackoverflow.com/questions/71102225

点赞
stackoverflow用户7185318
stackoverflow用户7185318

协程没有完成代码。它是否被垃圾回收了?

是的,它被垃圾回收了,因为在循环执行完成后协程没有引用。事实上,是否涉及到协程并没有什么区别;如果 iterator() 返回了一个 closure,它也同样会被垃圾回收。

您可以通过使用 collectgarbage 进行验证:

-- 声明函数,由于它们在全局表中,所以不会被垃圾回收
function collectgarbage_full()
    for _ = 1, 10 do -- 运行多个周期以确保即使使用了 Lua 5.2 或更高版本的分代 GC,所有垃圾也会被回收
        collectgarbage"collect"
    end
end
function powersOfTwo(i)
    coroutine.yield(i)
    powersOfTwo(2*i)
end
function iterator()
    return coroutine.wrap(function() powersOfTwo(1) end)
end
-- 统计未被垃圾回收的内存使用量
collectgarbage_full()
local used = collectgarbage"count"
-- 现在使用迭代器创建一个垃圾协程
for power in iterator() do
    print(power)
    if power > 1000 then break end
end
-- 回收垃圾,将使用量与垃圾协程之前的使用量进行比较
collectgarbage_full()
if used < collectgarbage"count" then
    error"未回收垃圾协程!"
end
print"协程已被垃圾回收。"

你应该会看到以下输出:

1
2
4
8
16
32
64
128
256
512
1024
协程已被垃圾回收。
2022-02-13 15:56:05