为什么我的尾递归函数不会暂停和刷新输出?

我已经查看了lua-users Sleep Function以找到一个非忙碌等待的解决方案来解决睡眠问题,但我对它们都不满意。尽管如此,我仍然尝试使用一些来在使用尾调用的函数末尾提供延迟。

通常我不会使用尾调用,但由于lua不会为尾调用留下堆栈,所以它适合我。

不幸的是,我看到我的处理器利用率飙升到约20%,一旦开始就立即变得无响应,而没有任何输出。

简化后的问题如下:

function myFunc ()
   -- 执行一些操作
   -- 大量花哨的逻辑和函数调用
   -- 呸,再加上一些打印
   print "Going to sleep"
   -- 睡眠一会儿
   os.execute("sleep 10")
   print "Waking up"
   -- 尾调用
   return myFunc()
end

我尝试了套接字选择方法、os.execute和忙碌等待。其中只有忙碌等待给出了预期的行为。

这些其他非忙碌等待的解决方案也是非阻塞的吗?也就是说,它们是否允许尾调用在延迟期间被处理?

如何在没有忙碌等待的情况下刷新输出并使函数等待10秒钟后再恢复?

点赞
用户759749
用户759749

根据 Nick Gammon 的建议,我尝试了他的 wait.lua 解决方案。我的初始尝试:

function controlLoop()
   wait.make (
      function()
         world.Note("Hello world.") -- essentially print
        wait.time(10)
     end
   )
   world.Note("Goodbye world.") -- essentially print
  return controlLoop()
end

遭受了完全相同的 100% CPU 使用率,没有输出显示的行为。

我的第二次尝试:

function controlLoop()
   wait.make (
      function()
         world.Note("Hello world.")
         wait.time(10)
         world.Note("Goodbye world.")
         return controlLoop()
      end
   )
end

已经运行了 3 个小时,没有故障。我确实调用了一个使用 debug.traceback() 获得栈跟踪的调试呼叫,但从未获得过超过 1 级深度的响应。此外,观察进程的 Window 内存使用情况,在 3 小时内它没有增加。

我很高兴我有一个解决方案,但我仍然有些不满意它为什么起作用以及原始版本为什么失败。

有人指出我正处于通道视觉状态,并且 while 循环完美解决了我的问题。

function controlLoop()
   wait.make (
      function()
         while true do
            world.Note("Hello world.")
            wait.time(10)
            world.Note("Goodbye world.")
         end -- loop
      end
   )
end

对此,我只能回复...duh,当然。

2015-10-17 21:13:19