PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Speicherleck durch pthreads



nobody0
11-02-2005, 04:31
In einem kleinen C-Programm wird ständig ein pthread erzeugt, vernichtet, erzeugt usw., so dass von dem Programm maximal 2 threads laufen.
Trotzdem ist nach ca. 1000 threads schluß, weil das Programm dann um 2 GB Speicher belegt hat, obwohl es kein malloc oder ähnliches verwendet!
Ich habe am Ende der thread-Funktion testweise statt pthread_exit auch return gesetzt, aber keine Änderung!

Hier die thread-Funktion:



// simple timeout
void *
func_timeout (void *threadid)
{
sleep (1); // timeout in s
if (0 >= g_fd) // device file could not be opened
{
printf ("ERROR: Timeout, device file could not be opened.\n");
exit (-1);
}
printf("thread exiting ...\n");
pthread_exit (NULL);
}


Wenn ich an dem Programm nur ändere, dass kein thread erzeugt wird, dann ist das Speicherleck weg.
Woher kann das Speicherleck denn kommen? :confused:

ExRevel
11-02-2005, 07:43
Hm, interessant, hast du das Programm mal mit valrgind und memcheck duchlaufen lassen, damit du siehst wo der Speicher verschwindet? Wenn jemand eine klare antwort hat wäre ich auch dankbar, da ich in codewars auch pthreads nutze, nur werden nicht so schnell so viele erzeugt und wieder gelöscht, also ist mir noch nichts so extrem aufgefallen.

ciao Exi

locus vivendi
11-02-2005, 08:44
Bitte ein vollständiges Beispiel posten, welches das Problem demonstriert. Sonst müssen aller rate. Mein erster "Verdacht" ohne dein Programm gesehen zu haben ist, du erzeugst "joinable" Threads aber joinst sie nicht.

ExRevel
11-02-2005, 10:48
Ok, da geb ich ihm Recht, das kann gut sein, also einfach mal den Bereich niederschreiben an dem du die Threadvariablen initialisierst und den Thread erzeugst.

nobody0
11-02-2005, 12:53
Nach Rumprobieren nach Beispiel-Programmen habe ich das Problem gefunden:

Das Speicherleck ist, daß pthread_join nicht zu jedem pthread_create aufgerufen wurde!

pthread_cancel statt pthread_join löst das Problem nicht.

Offensichtlich bleiben auch nach dem Terminieren eines Threads Recoucen übrig, die erst von pthread_join freigegeben werden.
Es ist wohl das Zombie-Problem; d. h. weil der Rückgabewert nicht abgefragt wird, werden vom terminierten Thread noch Recoucen belegt, obwohl man das den Man-Pages nicht entnehmen kann.
Anbei das Programm, mit dem es nun funktioniert, falls es jemanden interessiert.

nobody0
12-02-2005, 02:08
Nun gibt's ein anderes Problem, wenn durch den timeout-Thread das Programm neu starten soll: Mit



// simple timeout
void *
func_timeout (void *threadid)
{
sleep (1); // timeout in s
if (0 >= g_fd) // device file could not be opened
{
printf ("ERROR: Timeout, device file could not be opened.\n");
longjmp(env, 1234);
}
pthread_exit (NULL);
}


komme ich zwar wieder an den Anfang von main und erkenne dort ob der longjmp von dem thread erfolgte, aber nach dem longjmp funktioniert pthread_join nicht; d. h. die Thread-Resoucen werden nicht freigegeben :(
Und wenn nach dem longjmp vom Timeout-Thread pthread_exit (NULL) aufgerufen wird, erhalte ich
Ungültiger Maschinenbefehl
Vom Timeout-Thread den main-Thread zu terminieren ist wohl nicht möglich, weil dafür das pthread_t von main fehlt.
Irgendwelche Vorschläge? :confused: