我有一个不断执行的程序,我需要每分钟保存一次数据。
程序处理数据和每分钟我想保存变量的值并做一些统计操作来了解这个变量的变化。
我想我可以使用信号,SIGALRM和闹钟(60)。我的问题是,我可以将类方法作为SIGALRM的命运方法吗?
执行保存数据的方法并每分钟执行一些操作的任何其他想法吗?
该程序是用C ++编写的,在Linux中运行一个单核处理器。
答案 0 :(得分:4)
使用alarm
的解决方案将起作用,open
和write
都是异步信号安全的。虽然您必须知道alarm
和sleep
之间的互动未定义,因此请勿在同一计划中使用它们。
另一种解决方案,尤其是在您已使用epoll
的情况下,将timerfd
触发epoll
。这将避免可能的未定义交互。
至于实际储蓄,请考虑分叉。这是我从redis学到的一种技术(可能是其他人发明了它,但那是我从中学到的),我觉得这很酷。关键是分叉进程可以在Universe中花费所有时间来完成写入磁盘所需的数据。它可以在分叉时访问快照,而另一个进程继续运行和修改数据。并且由于在内核中完成了页面魔术,它仍然可以无缝地运行而不会有任何损坏的风险,而且不会停滞不前,也不需要查看类似异步IO的东西,这很棒。
答案 1 :(得分:2)
您可以使用boost bind
之类的方法调用类方法除此之外,我不建议使用信号,它们不是那么可靠,例如,可能会使你的一个系统调用过早地返回。
我会产生一个线程,假设你的单片并不意味着没有线程,等待60秒,获取锁,制作计算,输出和释放锁。
正如他们已经建议的那样,如果你有一个异步兼容系统(由事件驱动),你可以使用timerfd来生成事件。
答案 2 :(得分:2)
从信号处理程序保存数据非常糟糕。即使open
和write
是异步信号安全的,由于信号中断正在修改它的函数,您的数据很可能处于不一致状态。
更好的方法是添加到修改数据的所有函数:
if (current_time > last_save_time + 60) save();
当数据未被修改时,这将避免无用的保存。如果您不希望进行系统调用的开销来确定每个操作的当前时间,则可以安装更新current_time
的计时器/信号处理程序,只要您声明它volatile
另一个好方法是使用线程而不是信号。然后你应该使用互斥(或更好的,rwlock)来同步对数据的访问。