2011-05-21 57 views
8

在C中,如果我的應用程序意外結束,我可以在這之前調用函數嗎?我正在向數據庫寫入一個標誌(processRunning = 1),以防止其他應用程序啓動類似的進程。當應用程序結束時,它不會將該標誌改回。C:程序退出時做些什麼

回答

6

查看C標準庫的API atexit

+0

現貨。謝謝。 – 2011-05-21 14:15:40

+3

這不是一個解決方案。它不會保護您免受異常終止。 'atexit'函數在實踐中基本沒有用處,除了小程序永遠不會變大或變成圖書館之外,它的使用應該被認爲是有害的,因爲它必然涉及全局變量/全局狀態。 – 2011-05-21 14:54:42

+2

你們都可能已經知道這一點,但網絡中斷和電源故障等事情可能會阻止這類代碼的運行。每隔'n'分鐘向數據庫寫入時間戳可能會更加健壯,並且在沒有時間戳記的'n + m'分鐘後讓數據庫清理廢棄的標記。 – 2011-05-21 14:56:39

4

如果您的應用程序正常終止,它將運行通過atexit註冊的函數。這是標準功能,可在Windowsunix和其他所有平臺上獲得,也可在C++中獲得。

請注意,「正常終止」是指通過致電exit()或從main()返回。如果您的申請通過abort()_exit()終止,或者如果它從外部被立即殺害,它可能沒有機會做任何清理。可能會有更好的方法,可能會設置和清除包裝程序中的標誌,無論程序如何終止,或者完全取消該標誌,都會進行清理。

+0

感謝您的額外建議,Gilles。我正在考慮某事。類似於每隔幾秒檢查一次應用程序是否連接到特定PID的進程仍在運行。 – 2011-05-21 14:15:33

+0

一個解決方案可能是涉及捕獲信號。 (我認爲這不適用於Windows。) – 2011-05-21 14:16:48

+1

@Frank:當心PID檢查並非萬無一失。 PID可以被不相關的進程快速重用。 – Gilles 2011-05-21 14:17:41

2

有更好的方法來阻止應用程序運行兩次。一種解決方案是使用系統範圍內名爲互斥體的。另一個也許更簡單的解決方案是鎖定一個文件(開放寫入)。即使應用程序崩潰資源被操作系統釋放,您將能夠再次啓動應用程序,因爲文件或互斥鎖不會再被鎖定。

5

在POSIX上,正確的解決方案是使用共享內存中的強大互斥鎖來保護數據。如果你的進程死於一個強大的互斥體,另一個試圖鎖定互斥體的程序將不會發生死鎖,而是返回EOWNERDEAD,然後它有機會清除由互斥體保護的狀態並呼叫pthread_mutex_consistent

編輯:如果您只想防止程序的多個實例運行,那麼確實有更好/更簡單的方法,例如對數據庫文件進行鎖定。

+0

+1不知道。謝謝,弗蘭克 – 2011-05-21 15:15:29