Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Process Already Running

by Photius (Sexton)
on Sep 13, 2007 at 16:13 UTC ( [id://638843]=perlquestion: print w/replies, xml ) Need Help??

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

I read with interest, a thread started by Nitrox over 4 yrs ago, about detecting whether there is another copy of a script already running. If I am only needing to run on a Linux system, are there any disadvantages to doing something like this instead of using locks as described in that thread?
sub ProcessRunning { # If the passed string exists in the current Unix/Linux process list, # then this subroutine returns the lines from a "ps -e" command which # contain that string. These lines will look something like # "26787 pts/1 00:00:00 TestLoop.pl". If more than one running # process line contains that string, each of those lines will be # included in the returned value. Since this is Perl, these # returned values can be treated as TRUE if desired. # Make sure to specify a string that will uniquely locate the # processes of interest. Alternatively, the returned value could then # be further examined for other analysis. # # If the string does NOT exist, an empty value is returned, which # can be treated as FALSE. # # Sample usages: # exit if &ProcessRunning($myProcess); # OR # &ProcessRunning($myProcess) and die # "Another copy of process $myProcess is already running\n"; # OR # $result = &ProcessRunning($myProcess); # Examine $result for # further processing return 0 unless (`ps -e | grep @_ | grep -v grep`); } # end sub ProcessRunning

Replies are listed 'Best First'.
Re: Process Already Running
by Joost (Canon) on Sep 13, 2007 at 16:26 UTC
    That code doesn't work as described. It returns true if there are any programs running that match.

    anyway.

    Since you're not locking, you've just created a race condition: if two processes are started at around the same time, they will detect each other and both exit (provided the process name they're testing is static and their own - if the process name changes for some reason, it's possible that they won't detect each other and both will continue running).

      Thanks. I appreciate your reply. In my particular application, the three situations that you mention: 1) match multiple instances 2) both exit 3) neither exit if name has changed, are acceptable or even desirable. I forgot to mention that my scripts will be scheduled by cron to run every minute, but sometimes they will take more than one minute to complete. If one newly starting instance exits unnecessarily, it is ok since it will run again the next minute.

      What would not be acceptable though, would be if they both have the same name but, for some reason neither of them exit. I just figured that it might be less messy than having to deal with lock files, which if I understand the previous threads on the subject, can also have a race condition.
Re: Process Already Running
by erix (Prior) on Sep 13, 2007 at 16:27 UTC
Re: Process Already Running
by andyford (Curate) on Sep 13, 2007 at 16:20 UTC

    One problem is that you can have other processes that match that aren't the one you're looking for. For example, say your editing a program in vi at the same time that you're trying to see if that program is running. Then your grep might erroneously return an unwanted positive.

    non-Perl: Andy Ford

Re: Process Already Running
by fmerges (Chaplain) on Sep 13, 2007 at 16:53 UTC

    Hi,

    Aside, I normally use File::Pid in my own written programs.

    Regards,

    fmerges at irc.freenode.net
Re: Process Already Running
by shmem (Chancellor) on Sep 13, 2007 at 21:01 UTC
    A quick search on 'flock', author 'merlyn' turns up •Re: Checking for multiple instances.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      Thanks, shmem! That tip from the venerable merlyn works very nicely indeed!!!
Re: Process Already Running
by andreas1234567 (Vicar) on Sep 13, 2007 at 17:48 UTC
Re: Process Already Running
by Anno (Deacon) on Sep 13, 2007 at 17:52 UTC
    A PID-based approach to process exclusion suffers from the possibility of PID re-use. Also, there is usually no atomic way of checking the pid *and* registering it. That doesn't mean the approach can't be used in practice, but there is a small probability of malfunction.

    A safe approach can be based on file locking (flock), which is *meant* to guarantee exclusive access. The following code shows how that can be done in a Unix-ish environment. I'm sure there is already a module on CPAN (or two) that does this in a more portable way, but I couldn't find it in a hurry.

    #!/usr/local/bin/perl use strict; use warnings; $| = 1; use Fcntl qw( :flock); my $name = 'ttt'; # process name my $pid_file = "/var/run/$name.pid"; open my $pid_handle, '+<', $pid_file or die "Can't access '$pid_file': + $!"; flock $pid_handle, LOCK_EX | LOCK_NB or die "Process $name is still ac +tive"; truncate $pid_handle, 0 or die "Truncating '$pid_file' failed: $!"; print $pid_handle "$$\n"; # Normal processing starts here # # ... sleep 10; # for testing
    Update: I forgot to mention that the file /var/run/ttt.pid must be pre-created and given ownership and permissions so that the user that runs the process can write it.

    Anno

      Thanks for your suggestion. I must have fallen out of a tree and hit my head (or maybe I'm always this stupid). I just realized that the code in my original post would always return TRUE (script already running) because the script itself is, of course, already in the Linux process list when it checks to see if a script of it's same name is already running. Duh!!

      I'm not yet very familiar with Unix-ish systems and am not familiar with PIDs. In your sample code above, why did you open the pid file with +< (is this read-write but don't create?)? And what is the purpose for writing the Perl Process ID $$ to the file? Please help me understand how that is used?
        Heh, I didn't even notice the bug in your proposed scheme.

        In your sample code above, why did you open the pid file with +< (is this read-write but don't create?)?

        First off, I don't want to clobber the file before I've made sure I'm allowed to run. That's why plain write access won't do. Write access is required because many systems (foolishly, imo) forbid an exclusive lock on a file that's only open for reading. So even if I didn't intend to write my PID into the file (which is inessential, see below), simple read access would break in some places.

        And what is the purpose for writing the Perl Process ID $$ to the file? Please help me understand how that is used?

        That is absolutely inessential and not used at all. The locking scheme needs a file, unique to the specific program, that can be exclusively locked by the process. I have chosen a convention that is common in Unix systems, associating a process named ttt with a file /var/run/ttt.pid. As the name implies, it is commonly used to store the PID of the running process, and so I've done the same. The locking mechanism would also work without writing anything to the file, or with any other file for that matter.

        I forgot to mention (but will update) that you would have to pre-create the pid file /var/run/ttt.pid (once), and give it ownership and permissions that allow the process write access. A real program should probably explain that in an error message if the file is not found.

        Anno

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://638843]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (7)
As of 2024-03-28 08:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found