2

我是一个绝对的新手,甚至没有计算机科学背景。我只是一名机械工程师,试图实现一种远程监控我们安装的太阳能系统中逆变器的功率输出(和其他输出数据)的方法。所以如果我说了什么非常愚蠢的话,我提前道歉。

我正在尝试编写一个小的 ruby​​ 程序,它将存在于我的 ror 网站的数据库文件夹中。每 15 分钟(只要系统在线发电),我希望它轮询客户逆变器的数据(通过 TCPSocket 连接到连接到客户逆变器的网关)并用新数据更新我网站的数据库文件. 我的循环看起来像这样:

last_min = Time.new.min

while(1) do

tsec = Time.new.sec
tmin = Time.new.min

  if ( ( tsec == 0 ) && ( tmin - last_min == 1 ) )    # test using one minute
     # poll inverters, update database
     last_min = tmin
  end

end

当我第一次运行它时,它抛出了一个 Segmentation Fault 错误。然后我把它放在GC.disable上面,它工作正常(直到我在几分钟后强制退出),但这只是为了看看它是否是一个垃圾收集问题,它似乎是第一次创建时间对象触发问题(引发分段错误错误)。我知道我显然不能为无限循环禁用垃圾收集。但是我如何用红宝石“清理自己”?我可以在每次循环结束时以某种方式释放这些时间对象吗?我看到了一篇关于 的帖子GC.start,但不太明白它是如何工作的。

还有一种方法可以运行我的程序并查看它使用了多少 RAM?我将不胜感激任何人在这里可以给我的任何建议。(包括关于我在开头描述的太阳能输出监控系统的一般架构的建议!)

到目前为止,我已经从查看这里的所有帖子中受益匪浅,我提前感谢您!

4

2 回答 2

3

要强制垃圾收集,只需GC.start在循环结束时调用。任何可以被垃圾收集的东西都将被垃圾收集。

话虽如此,如果您真的只想让无限循环每分钟(或 15 分钟)执行一次操作,而不是比较 Time.now 分钟和秒,只需在无限循环中调用sleep即可。

loop do
  poll_inverters_and_update_db
  sleep 60
end

既然您提到您正在使用 Rails,您可能还想查看 delay_job 来执行此类操作,或者只是设置一个 cron 作业以每 n 分钟执行一次。

于 2011-05-11T20:36:09.383 回答
0

听起来是一个有趣的项目。

每个时间间隔只需要一个 Time 对象,因为您可以对时间进行算术运算。例如:

t0 = Time.new

while(1) do

  if ( Time.new - t0 >= 60 )    # test using one minute
     # poll inverters, update database
     t0 = Time.new
  end

end

那你就不用担心 GC 问题了。

PS。+1 用于使用delayed_job 或将其放入自己的线程中的其他方式,或者如果您可以将其作为自己的进程运行,则为cron,因为这样的循环或使用sleep() 会阻塞其他所有内容。

于 2011-05-11T20:36:56.997 回答