2011-04-08 51 views
1

我有一個不斷執行的程序,我需要每分鐘保存一次數據。在執行期間定期保存數據

程序過程數據和每一分鐘我想保存一個變量的值並做一些統計操作來知道這個變量的變化。我認爲我可以使它成爲一個信號,SIGALRM和報警(60)。我的問題是,我可以把類方法作爲SIGALRM的命運方法嗎?

任何其他的想法執行一個方法來保存數據,並每分鐘做一些操作?

該程序是用C++編寫的,在Linux中運行的是單核處理器。

回答

4

使用alarm的解決方案可以正常工作,openwrite都是異步信號安全的。雖然你必須知道alarmsleep之間的交互是未定義的,所以不要在同一個程序中使用它們。

不同的解決方案,特別是如果你已經使用epoll,將有一個timerfd觸發epoll。這將避免可能的未定義的交互。

至於實際節能,考慮分叉。這是我從redis(也許有人發明了它,但那是我從中學到的)學到的技術,而我認爲它非常酷。問題的關鍵在於,分支進程可以在宇宙中花費所有時間來完成寫入儘可能多的數據以達到磁盤的要求。它可以在分叉時訪問快照,而另一個進程繼續運行並修改數據。並且由於在內核中完成的頁面魔法,它仍然是所有無縫工作沒有腐敗的風險,而沒有熄火,也沒有做過需要看的東西像異步IO,這是偉大的。

+2

+1分叉,它處理它的非常優雅的方式。 – 2011-04-08 15:49:41

+0

謝謝。分叉看起來很好。我現在的問題是如何將處理過程中變量的即時值與時間計數過程進行通信。現在我記得所有流程的基礎知識。我認爲我的管道可能是溝通過程的最佳方式。 – 2011-04-08 17:59:55

+1

啊,那是叉子的魔力。你不需要交流任何事情。孩子知道父母知道什麼。操作系統將屬於父項的所有頁面映射到子進程中,並在寫入時將它們標記爲複製。這意味着即使父母在分叉之後修改了某些數據,孩子仍會看到原始值。這只是爲了不時地保存快照,除了每分鐘分叉一次(但完全忽略)之外沒有任何擔憂。一旦孩子完成儲蓄,讓它消失。 – Damon 2011-04-08 18:12:39

2

您可以使用類似boost bind

除了調用類的方法,我不會建議使用信號爲,他們是不是可靠,並且可以,例如,讓你的系統調用之一過早返回。

我會產生一個線程,假設你的單線程並不意味着沒有線程,等待60秒,鎖定,計算,輸出和釋放鎖定。

正如他們已經建議的那樣,如果您有一個異步兼容系統(由事件驅動),您可以使用timerfd來生成事件。

+0

對於線程(安全)解決方案+1。 – rturrado 2011-04-08 16:28:03

+0

是的,我不使用線程。 – 2011-04-08 17:49:40

2

從信號處理程序保存數據是非常糟糕的主意。即使openwrite是異步信號安全的,您的數據很可能是不一致的狀態,由於信號中斷這是修改它的功能。

更好的方法是添加到修改數據的所有功能:

if (current_time > last_save_time + 60) save(); 

這將避免無用當數據沒有被修改節省了。如果你不想做一個系統調用來確定每個操作當前時間的開銷,你可以改爲安裝更新current_time定時器/信號處理程序,只要你把它聲明volatile

另一個好方法是使用線程而不是信號。然後,您應該使用互斥鎖(或更好的rwlock)來同步對數據的訪問。

+0

好主意,但如果用戶在59秒內做了很多修改然後不保存並且程序崩潰怎麼辦? – Marlon 2011-04-08 16:24:01

+0

OP的原始想法(每60秒一次保存)具有完全相同的問題。 – 2011-04-08 16:29:19

+0

感謝您的回答,但我認爲分叉對我來說是更好的解決方案或更簡單。我不想使用線程。無論如何感謝 – 2011-04-08 18:03:55

相關問題