2011-08-07 7 views
5

Existe-t-il un moyen d'exécuter du code à la fin, quel que soit le type de terminaison (anormal, normal, non intercepté, etc.)? Je sais que c'est réellement possible en Java, mais est-ce même possible en C++? Im supposant un environnement Windows.Shutdown Hook C++

+2

Ce n'est pas possible en Java non plus - tous les processus sans tenir compte de la langue ne peuvent pas attraper le signal 9 sur linux (et l'équivalent sur Windows) ou exécuter n'importe quel code quand ce signal arrive – Soren

+0

Comme suggéré par @Drake, je choisirais [ atexit] (http://www.cplusplus.com/reference/cstdlib/atexit/). –

Répondre

5

Non - si quelqu'un invoque TerminateProcess, votre processus sera détruit sans plus tarder, et (en particulier) sans aucune chance de courir plus code dans la processus de fermeture.

+1

Ceci est la bonne réponse; Cependant, comme indiqué par certaines des autres réponses, vous pouvez configurer un exit-handler en utilisant 'atexit()' et vous pouvez attraper la plupart des signaux en utilisant 'signal()' - cependant vous ne pouvez jamais prendre d'action si quelqu'un force la terminaison serait kill-9 sur Linux, et le signal 9 est uncatchable) – Soren

+0

Merci, en fait j'avais peur de cette réponse – Paranaix

+0

aussi: assert(), abort(), terminate() –

2

Pour applciation de fermeture normale, je suggère

atexit() 
1

Une bonne façon d'aborder le problème utilise l'idiome RAII C++, ce qui signifie ici que les opérations de nettoyage peuvent être placés dans le destructor d'un objet, à savoir

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

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

Voir la Object Lifetime Manager dans la bibliothèque ACE. Au document lié, ils discutent aussi de la fonction atexit.

+0

Ci-dessus, j'ai supposé que la sortie est "normal ", c'est-à-dire pas via appel 'exit()', ou en raison d'une erreur de segmentation, etc. –

+1

Attention. Ce n'est pas garanti de travailler. Si une exception s'échappe de main(), alors l'implémentation est définie si la pile est déroulée. Donc, pour garantir cela, vous devez attraper toutes les exceptions dans main() (en plaçant votre code dans le bloc try). Vous n'avez pas besoin de faire quoi que ce soit juste de repenser l'exception afterwords. –

0

Pas pour tout type de terminaison; il y a des signaux conçus pour ne pas être manipulés, comme KILL sur Linux. Ces signaux sont conçus pour mettre fin à un programme qui a consommé toute la mémoire, le processeur ou d'autres ressources, et a laissé l'ordinateur dans un état qui rend difficile l'exécution d'une fonction gestionnaire.