> Bill Luebkert wrote:
>
> Darrin Barr wrote:
>
> > I'm trying to create a memory monitor process that is running as a
> > forked child while the parent rolls merrily along doing stuff. The
> > idea is for the main thread to do fancy processing on some
> data while
> > the child process keeps track of memory usage, threads,
> etc. When the
> > main thread of processing is complete, it signals the child
> process to
> > stop monitoring and to write some summary data. I've experimented
> > with WMI and Win32::Perflib. WMI gives me the info I want,
> but causes
> > a crash; Win32::Perflib doesn't have all the data I want.
> >
> >
> >
> > Below is a simplified example that demonstrates my problem.
> When the
> > forked child terminates, the perl interpreter crashes. If
> I let the
> > parent exit (which takes down the child), the perl
> interpreter crashes
> > with the following error:
>
> Try using process create instead of fork (I added a time
> check in the child in case kill should fail) :
>
> use strict;
> use Win32;
> use Win32::OLE qw(in);
> use Win32::Process;
> use Time::HiRes qw(gettimeofday tv_interval);
>
> if (@ARGV) {
>
> # connect to Windows Management Instrumentation Server
>
> my $Computername = Win32::NodeName();
> my $WMI = Win32::OLE->GetObject("WinMgmts://$Computername") or
> die "Can't connect to Windows Management
> Instrumentation server: $^E\n";
>
> # start monitoring until parent kills us or n seconds
> of execution
>
> my $t0 = [gettimeofday ()];
> while (1) {
>
> my $Computers = $WMI->ExecQuery(
> "SELECT * FROM Win32_OperatingSystem");
> foreach my $pc (in ($Computers)) {
> foreach my $object (in $pc->{Properties_}) {
> print
> "$object->{Name} => \t
> $object->{Value}\n" if
> ($object->{Name} =~
> /FreePhysicalMemory/);
> }
> }
>
> sleep 1;
>
> my $elapsed = tv_interval ($t0);
> if ($elapsed > 15) {
> print "Child exiting\n";
> exit;
> }
> }
>
> } else {
>
> my $Obj;
>
> Win32::Process::Create($Obj, $^X, "$^X $0 child", 0, 0, '.') or
> die "Win32::Process::Create: $!";
> sleep 10;
> print "Parent killing child\n";
> $Obj->Kill(2);
> print "Parent exiting\n";
> exit;
> }
>
> __END__
>
>
> --
> ,-/- __ _ _ $Bill Luebkert
> Mailto:[EMAIL PROTECTED]
> (_/ / ) // // DBE Collectibles Mailto:[EMAIL PROTECTED]
> / ) /--< o // // Castle of Medieval Myth & Magic
> http://www.todbe.com/
> -/-' /___/_<_</_</_ http://dbecoll.tripod.com/ (My
> Perl/Lakers stuff)
>
Bill, Appreciate the quick response. I thought about Win32::Process but ran
into a different issue.
* Since I don't know how long the parent is going to be processing (anywhere
from 3 minutes to several hours), the child can't be allowed to time out.
I'll kill everything manually if the parent seems to have hung...
* I am trying to limit the # of processes on the system (part of what's
being monitored), so starting another one for the "child" is less desirable
than using fork
* I need to let the child know when the parent's processing is done so it
can write out some summary statistics to a file. Killing the child prevents
that. That's why I was using a signal to communicate with the child. If I
use Win32::Process, the signal never makes it to the child (not sure why,
yet).
use strict;
use Win32;
use Win32::OLE qw(in);
use Win32::Process;
my $RunChild;
if (@ARGV) {
# must be the child, we have an argument...
# install signal catcher
$SIG{HUP} = sub { print "Caught signal!!!\n"; $RunChild = 0; };
# connect to Windows Management Instrumentation Server
my $Computername = Win32::NodeName();
my $WMI = Win32::OLE->GetObject("WinMgmts://$Computername") or
die "Can't connect to Windows Management Instrumentation server: $^E\n";
# start monitoring until parent kills us
$RunChild = 1;
my $maxFree = 0;
while ($RunChild) {
my $Computers = $WMI->ExecQuery("SELECT * FROM
Win32_OperatingSystem");
foreach my $pc (in ($Computers)) {
foreach my $object (in $pc->{Properties_}) {
if ($object->{Name} =~ /FreePhysicalMemory/) {
$maxFree = $object->{Value} if $object->{Value} > $maxFree;
print "$object->{Name} => \t $object->{Value}\n";
}
}
}
sleep 1;
}
# parent must have signalled...write out some summary data
print "\tMax Free: $maxFree\n";
# it's okay to die now...
} else {
# we're the parent, so create child process
my $Obj;
Win32::Process::Create($Obj, $^X, "$^X \"$0\" child", 0,
CREATE_NEW_CONSOLE, '.')
or die "Win32::Process::Create: $!";
# NOTE: Where I'm sleeping for 10 seconds, we're usually
# doing some intensive processing...
sleep 10;
print "Parent done...signalling child\n";
kill HUP => $Obj->GetProcessID();
print "Hope child is done...Parent exiting in 5\n";
sleep 5;
exit;
}
_______________________________________________
Perl-Win32-Admin mailing list
[EMAIL PROTECTED]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs