> 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

Reply via email to