2009-05-02 8 views
0

Ich arbeite an Code so etwas wie diesesWie frei dynamische zugewiesene Variable von SIGTERM frei?

... HEADERS ... 

int *var; 

void child() { 
    ... //some work 
    free(var); 
    exit(EXIT_SUCCESSFUL); 
} 

int main(void) { 
    ... 
    //allocate variable 
    var = (int *) malloc(N*sizeof(int)); 
    ... //work with var 

    for(int i; i<PROC_COUNT; i++) { 
    pid_t child = fork(); 
    if(pid == 0) { 
     child(); //main function of new proces 
     break; 
    } 
    elseif(pid < 0) { 
     //there is enormous problem -> kill every proces 
     kill(0, SIGTERM); 
     waitpid(0, NULL, 0); //wait for children 
     free(var); 
     exit(EXIT_FAILURE); 
    } 

    } 
    free(var); 
    return EXIT_SUCCESS; 
} 

Wenn Prozess gegabelt ist, werden alle Variablen zu geklont. Im Normalfall werden alle Kopien von var freigegeben.

Wenn es einen Fehler von fork() gibt, sende ich Signal SIGTERM an alle erstellten Prozesse. Und ich muss Signalhandler für SIGTERM schreiben, die var freigibt und Anwendung beendet. Allerdings ist free() nicht signal safe function - also sollte ich es nicht nennen. Aber wie frei() diese Variable?

Vielen Dank für Ihre Antworten ...

EDIT: valgrind zeigt auch noch reacheable Variable:

==5928== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 1) 
==5928== malloc/free: in use at exit: 20 bytes in 1 blocks. 
==5928== malloc/free: 1 allocs, 0 frees, 20 bytes allocated. 
==5928== For counts of detected errors, rerun with: -v 
==5928== searching for pointers to 1 not-freed blocks. 
==5928== checked 49,164 bytes. 
+0

Enemouse? Ist das eine Art großes prähistorisches Nagetier? :-) – JesperE

+0

Ich bitte um Verzeihung, es ist ein bisschen spät, in der Slowakei, also habe ich Fehler gemacht. Danke für die Nachricht. – izidor

Antwort

4

Ich bezweifle, dass Sie müssen. Jedes Betriebssystem, das fork() unterstützt, wird automatisch Zuteilungen von malloc() freigeben, wenn ein Prozess beendet wird, unabhängig davon, wie dies geschieht (einschließlich der Beendigung).

Es gibt Umgebungen, in denen C-Programme nicht in Prozessen laufen, und wo Sie sehr vorsichtig sein müssen, was Sie am Ausgang herumliegen lassen. Diese Umgebungen sind jedoch nicht POSIX und unterstützen nicht fork(). Sie könnten Signale nicht unterstützen. Wenn Sie für eine solche ungewöhnliche Umgebung schreiben, überprüfen Sie Ihre Dokumentation ...

Wenn Sie einen sauberen Valgrind-Bericht anzeigen möchten, könnte der Handler ein Ereignis in die Ereignisschleife des Kindes einbetten (oder eine Markierung setzen) und post ein Semaphor, oder was auch immer), und verarbeiten Sie das Ereignis als einen sauberen Ausgang. Das würden Sie auch tun, wenn Ihr Programm eine interaktive Anwendung wäre und Sie die Daten des Benutzers auf einem SIGTERM speichern wollten, vorausgesetzt, Ihr UI-Framework hat SIGTERM noch nicht in ein Ereignis für Sie übersetzt.

+0

Warum zeigt Valgrind immer noch erreichbaren Speicher? (Vielleicht hast du Recht und der von Valgrind angezeigte Müll wird durch falsche Art von Valgrind-Messung erstellt) – izidor

+0

Valgrind versucht dich zu warnen, dass du den Speicher vor dem Beenden nicht freigegeben hast. Gleich danach wird es vom Betriebssystem freigegeben. Normalerweise würde dieser Bericht von Valgrind Sie misstrauisch machen, dass Ihr Programm vielleicht den Überblick über den Speicher verloren hat. Aber im Fall eines SIGTERM-Exits können Sie dies ignorieren: Sie wissen, dass Sie Ihre normale Bereinigung nicht durchgeführt haben, also erwarten Sie falsche Behauptungen von "Speicherlecks". –

+0

Okay, danke. Ich fragte mich, ob es möglich war, diese problematische Sache zu korrigieren. Vielen Dank! – izidor

0

ich etwas Missverständnis sein kann, aber sicher nach SIGTERM des gesamte Prozess wird verschwinden, nimmst du deine Variable mit?

0

Sie könnten exec verwenden, um den Child-Prozess von main zu starten, anstatt die child() -Funktion direkt aufzurufen. Verwenden Sie ein Befehlszeilenargument, um dem untergeordneten Programm mitzuteilen, dass es die Arbeit in main ausführen soll. Dann kann der Child-Prozess ordnungsgemäß aufgeräumt werden.