2011-08-12 21 views
1

如何設計一個C/C++程序,以便在接收到中斷信號後保存一些數據。中斷正在運行程序並保存數據

我有一個長時間運行的程序,可能需要在完成運行之前殺死(例如,通過按Ctrl-C)。當遇害(而不是結論)程序應該能夠將一些變量保存到磁盤。我有幾本大型Linux書籍,但不知道從哪裏開始。食譜食譜會非常有幫助。

謝謝。

回答

4

要做到這一點,您需要讓程序監視某些東西,例如全局變量,這會告訴他停止正在執行的操作。

例如,假設您的長時間運行的程序執行一個循環,你可以這樣做:

g_shouldAbort = 0; 
while(!finished) 
{ 
    // (do some computing) 

    if (g_shouldAbort) 
    { 
     // save variables and stuff 
     break; // exit the loop 
    } 
} 

與g_shouldAbort定義爲全局揮發性變量,像:

static volatile int g_shouldAbort = 0; 

(將其聲明爲「volatile」是非常重要的,否則編譯器會發現沒有人在循環中寫入它,可能會認爲如果(g_shouldAbort)總是錯誤且opti邁茲它扔掉)

然後,使用例如信號 API其他用戶的建議,你可以這樣做:

void signal_handler(int sig_code) 
{ 
    if (sig_code == SIGUSR1) // user-defined signal 1 
     g_shouldAbort = 1; 
} 

(您需要註冊,當然這個處理程序,比照here

signal(SIGUSR, signal_handler); 

然後,當你「送」的SIGUSR1信號給你的程序(與殺例如命令),g_shouldAbort將被設置爲1,你的程序將停止其計算。

希望得到這個幫助!

注意:這種技術很簡單,但粗糙。正如其他用戶所概述的那樣,使用信號和全局變量使得難以使用多線程。

0

使用signal(2)sigaction(2)爲函數指針分配SIGINT信號,並在那裏進行清理。

4

你想要做的並不是微不足道的。您可以先使用signalsigaction安裝SIGINT(C-c)的信號處理程序,但之後會啓動硬件部分

主要問題是,在信號處理程序中,您只能調用async-signal-safe functions(或reentrant函數)。大多數庫函數不能可靠地被認爲是可重入的。例如,stdio函數,malloc,free和許多其他不可重入。

那麼你如何處理呢?在你的處理程序中設置一個flag(將一些全局變量done設置爲1)並查找EINTR錯誤。在處理器之外進行清理應該是安全的。

0

讓你在你保存功能

// somewhere in main 
signal(SIGTERM, signalHandler); 
signal(SIGINT, signalHandler); 

void saveMyData() 
{ 
    // save some data here 
} 

void signalHandler(int signalNumber) 
{ 
    static pthread_once_t semaphore = PTHREAD_ONCE_INIT; 
    std::cout << "signal " << signalNumber << " received." << std::endl; 
    pthread_once(& semaphore, saveMyData); 
} 

只輸入一次,如果你的進程中取得2點以上的信號,你寫完你的文件,你可以節省怪異數據

+0

for C++你可以考慮boost :: call_once – Nelstaar

3

你想什麼之前確實屬於檢查點/重新啓動的範疇。

在檢查點/重啓時使用信號驅動方案有幾個大問題。一個是信號處理器必須非常緊湊和非常原始。您不能在信號處理程序中寫入檢查點。另一個問題是當信號發送時,你的程序可以在任何地方處於其執行狀態。這個隨機位置幾乎可以肯定不是一個安全點,檢查點可以從這個位置丟棄。還有一個問題是,您需要爲您的程序提供一些應用程序端檢查點/重新啓動功能。

而不是滾動自己的檢查點/重新啓動功能,我建議你看看使用一個已經存在的免費檢查點。 Linux上的gdb提供了檢查點/重新啓動功能。另一種是DMTCP,參見http://dmtcp.sourceforge.net/index.html

相關問題