Arbeitsspeicher von Perl Threads wieder freigeben

A

aktiv

Grünschnabel
Hallo Leute,

sitze an einem Problem mit Perl Threads.
Ich habe ein Perl Programm geschrieben das eine Menge Threads erzeugt. Die Threads werden alle nacheinander abgearbeitet, soweit sogut...

Das Problem liegt nun darin, das jeder Thread sich automatisch ca. 8MB Arbeitsspeicher gönnt und diesen nach dem Durchlauf auch nicht wieder freigibt.
Dh -> mit jedem neuen Thread + 8MB Arbeitsspeicher sind dann schon nach ca 200 Threads 1600Mb...

hier einamal der Beispielhafte Programmcode
Code:
#!/usr/bin/perl

use threads;
use threads::shared;

foreach my $inArbeit(1...200)
{
   my $t = threads->new(\&threadMain, $inArbeit);

}

sub threadMain {

#...
	return 1;
}

Nachdem ein Thread durchlaufen ist soll nun der gesamte Speicher dieses Threads wieder freigegeben werden. Dies klappt aber irgendwie nicht. Hab da schon verschiedene Sachen ausprobiert gegooglet usw....
Das Problem wird öfters angeschnitten, aber adequate Lösungen gibt es nciht. Oder ich bin zu doof dazu:)

Die DESTROY Funktion soll woll ein Weg sein, aber wo die hinsoll ist mir ein Rätsel.
oder einfach sowas
Code:
undef $t;
geht auch nicht:(

Vielleicht hat ja einer eine Idee...

Grüße an alle!
 
Du wirst vermutlich nicht drumrum kommen jede Variable im Thread explizit freizugeben bevor er zum Elternprozess zurückkehrt.
 
Moin danke für die Antwort, wenn du damit meinst das ich es 'joinen' soll, dann hast du verdammt recht, jetzt gehts nämlich wie gewünscht.
Eine Kleinigkeit hat große Wirkung:
#!/usr/bin/perl

use threads;
use threads::shared;

foreach my $inArbeit(1...200)
{
my $t = threads->new(\&threadMain, $inArbeit);

#neu
$t->join();

}

sub threadMain {

#...
return 1;
}

In meinem Gesamten Programm wird nun ein Speicher von 0,1% verwendet. Vorher warens ca 13%.
Wenn ichs richtig verstehe, dann wartet jetzt explizit aufs Ende des Thread und beendet ihn dann sauber.
 
Daran hatte ich gar nicht gedacht. Der Return-Wert muss ja auch abgeholt werden, sonst wartet der Thread auf den Eltern-Prozess, da er noch an diesen gebunden ist. Das logische Verhalten wäre, dass der Thread erst zerstört wird, wenn der Eltern-Prozess den Return-Wert abgefragt hat, weil dieser mit der Zerstörung des Threads sonst auch weg wäre. Vermutlich würde ein detach() es auch tun, wenn man den Rückgabewert nicht braucht.
 
Zuletzt bearbeitet:
Moinsen, hier nochmal abschließend die Lösung zu meinem Problem.

#!/usr/bin/perl

use threads;
use threads::shared;

my @t;
foreach my $inArbeit(1...200)
{
$t[$inArbeit] = threads->new(\&threadMain, $inArbeit);

foreach (@t){
if($_->is_joinable()){
$_->join()
}
}
}

sub threadMain {

#...
return 1;
}

So in etwa funktioniert das. (Ist ungetestet zur Illustration ;)) Mit 'is_joinable()' kann man abfragen ob ein Thread beendet ist. Falls ein Thread beendet ist kann er mit 'join()' beendet werden. In diesem Moment wird der Speicher wieder freigegeben.
Nutzt man 'join()' kann man einen Rückgabewert mit übergeben. Z.B. '$rueckgabe = $t->join();'.
Nutzt man 'detach()' wie von bitmuncher vorgeschlagen, dann wird der Thread automatisch beendet wenn er durch ist. Ein Rückgabewert an den Aufrufer gibts da nicht.

Vielleicht hilft dieser Post dem Ein oder Anderen :)
Greetz & THX an bitmuncher
 
Zurück
Oben