in reply to threads: spawn early to avoid the crush.
On the other hand, if you set $self->{'reuse'} = 1; and comment out the line
my @ReturnData = $z->{'thread'}->join;
the threads will run in parallel and the memory climbs with each thread.
So the trick, is to find a way to have the main watch for each thread when it is ready to join, then relaunch it, instead of making another thread object. That is why it is easier with Tk, Gtk2, POE, etc, where you can have an event loop watching the thread. I am toying with the idea of how to put a self-contained method in the object to watch for the thread finishing it's code run.
You could set the thread to be non-reuse and detach it. Then have the Zthread object store the return value in it's object. Then the main program would just have to wait an amount of time, and get the thread returns out of the Zthread object, and undef the object. That will be my next step.
#!/usr/bin/perl use warnings; use strict; $|=1; package Zthread; use threads; use threads::shared; sub new { my ($class, %arg) = @_; my $self = { # 'name' => $arg{-name}, #identifying name # 'reuse' => $arg{-reuse}, # control reuse of thread }; bless $self; threads::shared::share($self->{'counter'}); threads::shared::share($self->{'go'}); $self->{'counter'} = 0; $self->{'go'} = 0; $self->{'die'} = 0; #sets whether threads are kept alive, but sleeping #after a run finishes $self->{'reuse'} = 0; $self->{'thread'} = threads->new( sub{ while(1){ if($self->{'die'} == 1){ goto END }; print $self->{'go'}; if ( $self->{'go'} == 1 ){ # eval( system( $self->{'data'} ) ); foreach my $num (1..20){ print 'Thread-> ',$self->{'counter'},"\n"; + $self->{'counter'}++; select(undef,undef,undef, .1); if($self->{'go'} == 0){last} if($self->{'die'} == 1){ goto END }; } if( ! $self->{'reuse'} ){ print "We are done boss->$self->{'counter'}\n"; goto END; }else{ print "We are done boss->$self->{'counter'} .... + going to sleep\n"; $self->{'go'} = 0; #turn off self before returning } }else { select(undef,undef,undef, .1); } } END: return "We are done boss->$self->{'counter'}\n"; }); return ($self); } ################################################### sub start { my $self = shift; $self->{'go'} = 1; } ################################################ sub getCounter { my $self = shift; return $self->{'counter'}; } 1; package main; my @psizes; foreach my $run (1..10){ my $z = Zthread->new(); $z->start(); print "wait end marker for \n"; #commenting out the following line will make them run #in parrallel but memory will climb each run my @ReturnData = $z->{'thread'}->join; my @size = split "\n", `cat /proc/$$/status`; (my $vmsize) = grep { /VmSize/ } @size; my (undef, $size) = split ' ', $vmsize; # print "\nThread returned @ReturnData Size->$size\n"; print "\nThread returned Size->$size\n"; push @psizes, $size; } print "@psizes\n"; <>; __END__
|
---|