2011-08-07 14 views
5

jest jakiś sposób uruchomienia kodu na zakończenie, bez względu na rodzaj zakończenia (nienormalny, normalny, nieprzechwycony wyjątek itp.)? Wiem, że jest to możliwe w Javie, ale czy jest to nawet możliwe w C++? Zakładam, że środowisko Windows.Shutdown Hook C++

+2

Nie jest to również możliwe w Javie - wszystkie procesy, niezależnie od języka, nie mogą przechwycić sygnału 9 na linuksie (i odpowiedniku w systemie Windows) lub uruchomić dowolny kod po nadejściu sygnału – Soren

+0

Jak sugerował @Drake, chciałbym wybrać [ atexit] (http://www.cplusplus.com/reference/cstdlib/atexit/). –

Odpowiedz

5

Nie - jeśli ktoś powołuje TerminateProcess, Twój proces zostanie zniszczona bez dalszych adieu, i (w szczególności) bez jakiejkolwiek szansy uruchomić dowolny kod w więcej proces zamykania.

+1

To jest właściwa odpowiedź; jednakże, jak wskazują niektóre inne odpowiedzi, możesz ustawić obsługę wyjścia używając 'atexit()' i możesz złapać większość sygnałów za pomocą 'signal()' - jednak nigdy nie możesz podjąć żadnej akcji, jeśli ktoś wymusi zakończenie (byłby zabójca-9 na Linuksie, a sygnał 9 jest nieczytelny) – Soren

+0

Dziękuję, faktycznie bałem się tego odpowiadam – Paranaix

+0

także: assert(), abort(), zakończ() –

2

do normalnego zamknięcia applciation Proponuję

atexit() 
1

Dobrym sposobem podejścia do tego problemu stosuje idiom C++ RAII, co oznacza tutaj, że operacje oczyszczania można umieścić w destructor obiektu, tj

class ShutdownHook { 
    ~ShutdownHook() { 
    // exit handler code 
    } 
}; 

int main() { 
    ShutdownHook h; 
    //... 
} 

Patrz Object Lifetime Manager w bibliotece ACE. W połączonym dokumencie omawiają także funkcję atexit.

+0

Powyżej założyłem, że wyjście jest "normalne" ", tzn. nie przez np wywołanie 'exit()' lub z powodu błędu segmentacji, itp. –

+1

Ostrożnie. To nie gwarantuje działania. Jeśli wyjątek jest wyłączany w funkcji main(), wówczas w implementacji zdefiniowano, czy stos został rozwinięty. Aby zagwarantować to działanie, musisz przechwycić wszystkie wyjątki w main() (umieszczając swój kod w bloku try). Nie musisz nic robić, po prostu wyrzuć wyjątki. –

0

Nie do żadnego rodzaju rozwiązania; istnieją sygnały, które są zaprojektowane, aby nie być obsługiwane, jak KILL na Linuksie.

Sygnały te mają na celu zakończenie programu, który pochłonął całą pamięć, procesor lub inne zasoby, i pozostawił komputer w stanie, który utrudnia uruchomienie funkcji obsługi.