2011-11-01 46 views
0

我有一個在單線程C應用程序中定義的關閉鉤子處理程序。關閉C應用程序以確保完成CRITICAL部分的正確方法?

int main(int argc, char * argv[]){ 
    //Shutdown hook for CTRL-C 
    (void) signal(SIGINT, shutdownHook); 
    ... 
    ... 
} 

因此,當用戶點擊CTRL-C關閉鉤啓動...

void shutdownHook(int sig){ 
    rc = wmq_sender_stop(errorStr); 
    if (rc != 0){ 
     printf("\n%s\n", errorStr); 
    } 
    while(transactionRunning == TRUE){ 
     sleep(1); 
     printf("Transaction still running\n"); 
    } 
    .... 
    .... 
} 

你可以看到上面我所說的「wmq_sender_stop」程序(在共享庫)基本上將變量設置爲FALSE以結束該共享庫中的循環。

int wmq_sender_stop(char errorStr[ERROR_STR_LEN]){ 
     running = FALSE; 
     ... 
} 

並且變量「running」將停止(希望)在該共享庫中運行的主循環。

while(running == TRUE){ 
... 
... 
} 

我遇到的問題是,在我的Linux系統中所有的工程100%...但是,當我一個很大的功能強大的服務器上安裝應用程序,它調用「wmq_sender_stop」,並設置可變細,但似乎就像應用程序在服務器上運行速度太快以允許「while(running == TRUE)」變量退出.....或者它只是簡單地返回到主應用程序,並且「while(transactionRunning == TRUE )」循環只是連續運行...

本質的大型服務器上,如果我打CRTL-C以下是時間可持續輸出到屏幕:

Transaction still running 
Transaction still running 
Transaction still running 
Transaction still running 
Transaction still running 
Transaction still running 
... 

也許我需要在這裏創建線程,並在它們之間進行相互通信,但是它們沒有更簡單的方法來優雅地允許「共享庫中的循環」在關閉之前結束它的「關鍵代碼/事務」,即使在極速服務器?爲什麼它在我的linux筆記本電腦上工作?

如果我需要使用線程什麼是最好的和最快的方式,他們comminucate?目前我正在使用CALLBACKS ....但不確定最適合線程的IPC是什麼?

感謝您的幫助,非常感謝

林頓

+0

什麼在您的Linux機器上將'transactionRunning'設置爲FALSE?如果它是一個單線程應用程序,它不會改變它的'sleep/printf'循環... –

+1

通常,在信號處理程序(或I/O)中執行長時間運行的任務並不是一個好主意。而是在信號處理程序中發送一個「信號」給主線程並完成所有工作。 –

+0

正如你所說的應用程序是單線程的,當應用程序在SIGINT處理程序中循環並等待時,共享庫沒有機會退出其循環。一個明顯的事實是,它看起來好像它會按照你希望它應該在你的Linux機器上那樣工作,儘管它不應該。服務器上的行爲對我來說看起來完全沒問題。 – alk

回答

2

確保running(和transactionRunning也被聲明爲volatile)。否則,在某些情況下,C編譯器可能會緩存它的值。現在,想到volatile意思是「該值可以通過信號處理程序進行更改」。

請注意,你必須要小心這樣的代碼:

rc = wmq_sender_stop(errorStr); 

如果你這樣做,在信號處理程序,你最好希望,這一功能是安全地從信號處理程序調用。大部分功能都沒有。 (甚至可以安全地從多個線程調用的函數對於來自信號處理程序的調用是不安全的。)

最後一個問題是,如果您的代碼是單線程的,但您永遠不會從您的信號處理程序返回,那麼您主循環應該退出?信號處理程序在您的應用程序的現有線程中運行。通常情況下,您希望在信號處理程序中執行的唯一操作是更改標記爲volatile的全局變量的值,然後返回。

+0

好點:我完全同意宣佈'運行'不穩定。如果你已經解釋了爲什麼'wmq_sender_stop'可能會被unsafed從信號處理程序中調用,我會投你的答案。 – alk

+0

@alk:我對「wmq_sender_stop」一無所知,所以我沒有理由認爲它是安全的。從信號處理程序調用大多數函數是不安全的(例如,包括'printf')。沒有必要告訴人們你隱瞞upvotes,你可以要求澄清。 –

+0

好吧,假設最糟糕的情況是最安全的方法,謝謝澄清... - 請原諒我關於投票的不相干的附註。 – alk

0

爲什麼不叫wmq_sender_stop(),比通過return離開信號處理程序。共享庫中的循環將退出,所以你的應用程序將會這樣做,不是嗎?

+0

但是沒有時間問題呢?如果主應用程序在shard lib中的循環結束之前結束,會發生什麼情況? –

+0

@Lynton Grice爲什麼應該主要的應用程序結束? – alk

相關問題