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

Hi Monks

I wrote the next code:
#!/usr/bin/perl STAGE1: while (1) { $l=system "pslist|grep process_name>!temp"; if ($l=="256") { sleep(1); } else { sleep(1); goto STAGE2; } } STAGE2: while (1) { $l=system "pslist|grep process_name"; # print "$l \n"; if ($l=~"256") { sleep(1); #Code 4 execution here unlink "!temp"; goto STAGE1; } else { sleep(1); } }

this code runs a system command called "pslist"
(you can get it from www.sysinternals.com)
from it using "grep" I check if a certain process runs,
when it runs I wait for its end, then I execute a code.
After execution I return to waiting position.

the problem with this code is that it sometimes misses runs shorter then 1 second,
and if I reduce the sleep parameter to less then 1 second the CPU usage jumps to the sky.

if anyone have a more efficiant and less CPU consuming way
of doing it,
please Help.

Thanks Ahead,
Moked

Replies are listed 'Best First'.
Re: Starting a script according to processes
by Zaxo (Archbishop) on Jan 10, 2005 at 13:33 UTC

    Perhaps it would be useful to just check the time the executable was last run. It would certainly save a lot of polling the process table. The idea is to check access time on the file. To be extra careful, also check that it doesn't match mtime. That would indicate that the file had been changed, not run. That still errs if the file has been read instead of run.

    use Time::Local; my $exe = '/usr/bin/foo'; my ($atime, $mtime) = (stat $exe)[8,9]; print $exe, " just ran.\n" if timelocal(localtime) - $atime < 10 and $mtime < $atime;

    After Compline,
    Zaxo

Re: Starting a script according to processes
by zentara (Cardinal) on Jan 10, 2005 at 13:36 UTC
    I only can give you some ideas I had, when I read your post. First, doing while(1) is just asking for cpu trouble. Second, if you need to get subsecond resolution, you will need another approach.

    Maybe POE has an example to do this simple task?

    I don't know how pslist outputs. But if it has a mode to give continuous output, like top, maybe you could set up a filehandle read on it, so you would only have to open it once( you may need to rewind the filehandle ). Then you could use IO::Select on it when it was readable.

    Here is a simple idea using IPC::Open3. This uses relatively little cpu, at .1 second.

    #!/usr/bin/perl use warnings; use strict; use IPC::Open3; my $pid = shift || $$; my $pid1 = open3(\*WRITE,\*READ,0,"/bin/sh"); #if \*ERROR is false, STDERR is sent to STDOUT while(1){ print WRITE "ps -o rss= -p $pid\n"; select(undef,undef,undef,.1); my $size = <READ>; #do your checks here and do whatever print "$size"; }

    I'm not really a human, but I play one on earth. flash japh
Re: Starting a script according to processes
by ZlR (Chaplain) on Jan 10, 2005 at 16:05 UTC
    Hello,

    Since you are using pslist i assume you're on win32. Then , instead of using a system call to get the process list you could use something like this code (there's a better thread about it somewhere but i can't seem to find it just now) .

    It uses Win32::PerfLib to return a list of process and PIDs. This will save CPU time, only not enough to fight against a while (sleep 1) :|

    ZlR.

Re: Starting a script according to processes
by ikegami (Patriarch) on May 31, 2009 at 07:42 UTC

    and if I reduce the sleep parameter to less then 1 second the CPU usage jumps to the sky.

    sleep expects a whole number of seconds. Anything less than 1 gets truncated to zero ...unless you use sleep from Time::HiRes. This is documented.

    For delays of finer granularity than one second, the Time::HiRes module provides usleep().

Re: Starting a script according to processes
by Grygonos (Chaplain) on Jan 10, 2005 at 14:08 UTC

    Not really related to the current problem, but in your code you use the variable $1 this is a perl variable for capturing matches in regular expressions. I would refrain from using it in the future, as it may cause side effects in code that use regular expressions.

      in your code you use the variable $1
      Er, actually he's using an ell, not a one. It's still a poor choice of name though!

      Dave.