2011-05-11 65 views
2

我是一个绝对没有计算机科学背景的新手。我只是一名机械工程师,试图实施一种方法来远程监控我们安装的太阳能系统中逆变器的功率输出(和其他输出数据)。所以如果我说什么都很愚蠢的话,我提前道歉。创建Ruby时间对象导致垃圾回收问题

我想写一个小的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使用,因为它去了吗?我希望任何人和所有的建议可以在这里提供给我。 (包括我开始介绍的太阳能输出监控系统的总体结构的建议!)

我已经从迄今为止在我的旅程中查看此处的所有帖子深深受益,并且我提前感谢您!

回答

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()会阻止其他所有内容。

+0

我刚刚发现了一个叫做“when”的漂亮宝石,帮助我设置了一个cron作业。非常感谢您指引我朝着正确的方向发展!我会让你知道它是怎么回事! – pitachip 2011-05-11 21:20:05

3

要强制垃圾收集,只需在循环结束时调用GC.start即可。任何可以收集垃圾的东西都会被垃圾收集。如果你真的想要一个无限循环,每分钟(或15分钟)做一些事情,而不是比较Time.now分钟和秒,只需在无限循环内调用sleep即可。

loop do 
    poll_inverters_and_update_db 
    sleep 60 
end 

既然你提到你是使用Rails,你可能还需要考虑的delayed_job做这种类型的事情,或者只是建立一个cron作业执行每n分钟。

+0

是的,使用睡眠,否则循环需要100%的CPU。 – steenslag 2011-05-11 20:41:18

+0

我唯一的问题就是睡眠()我实际上是希望在15分钟内每15分钟轮询一次数据,因此客户可以全部“哦,我的系统在上午11:15生产3.8千瓦”并且不完全是24小时的时间长度和闰年...你知道。它看起来像我应该看看这个delayed_job或cron工作方法(我不知道是什么)。你认为这两种方法中的哪一种对这项工作会更好? – pitachip 2011-05-11 21:09:05

+1

如果你想在15分钟内每15分钟发生一次,那么最简单的事情就是配置一个cron作业。 */15 * * * */path/to/your/script是您的crontab可能的语法。你的脚本只需要执行'poll_inverters_and_update_db'。 – 2011-05-12 02:07:19