Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Ok, I am using this code:
my $t = new Proc::ProcessTable; foreach my $p ( @{$t->table} ){ if($p->cmndline =~ / member.cgi/) { my $_sec = time() - $p->start; my $_pid = $p->pid; if($_sec > 3 && $pid->is_pid_running($_pid)) { $pid->kill( $_pid ); print qq~$_pid was running for $_sec seconds...\n~; } } }
My question is this...
Is there a way to make this more efficient, instead of doing this:
foreach my $p ( @{$t->table} ){ if($p->cmndline =~ / member.cgi/) {
Is there a way to get the table to only give me the pids running with member.cgi contained in the cmndline field? That way it does not have to go through the 200+/- other processes to find those ones?

If not, this works as it is, I was just hoping to make it more efficient.

Thanks,
Richard

BTW, this script should be done running in less than 0.5 seconds so I have it find those that have been running for more than 3 seconds as those ones should have exited out but for some reason are hanging. I am thinking there is a server issue I see when I run the hanging ones I see some sock errors, even though that script does not use sock for anything, Perl does pull in a sock library on this machine. I am not sure if that error is related to the hanging though.

Replies are listed 'Best First'.
Re: using Proc::ProcessTable
by Anonyrnous Monk (Hermit) on Feb 13, 2011 at 11:25 UTC
    ...find those that have been running for more than 3 seconds as those ones should have exited out but for some reason are hanging.

    Do you have control over the code of member.cgi?  If so, you could also try having those processes terminate themselves after 3 seconds:

    #!/usr/bin/perl alarm 3; # have the OS send myself a SIGALRM after 3 seconds for (1..100) { print "sending line $_\n"; select undef, undef, undef, 0.5; } print "Done.\n";
    $ ./887855.pl sending line 1 sending line 2 sending line 3 sending line 4 sending line 5 sending line 6 sending line 7 Alarm clock

    (The default action upon a process receiving SIGALRM is to terminate it, but you can of course set up your own signal handler, like $SIG{ALRM} = sub { ...clean up...; exit 1 }; or $SIG{ALRM} = sub { kill 9, $$ }; )

      SWEET! That works!!! Fantastic. Thank you much!

      Richard