Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

Checking for multiple instances

by MarkNo1 (Initiate)
on Sep 24, 2004 at 17:02 UTC ( #393593=perlquestion: print w/replies, xml ) Need Help??

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

Hello All,

I have googeled and searched the monastery in search of an answer to my question but keep coming up with the same answer. I have a bunch of perl scripts which are executed via cron. Occasionally server load gets high enough for one perl script to be already running when it gets executed again by cron.

Without using a lock file that I create myself (which is fraught with problems) I want to be able to check for existing instances of the same perl script. I am _positive_ that there must be a CPAN module that'll help me but I cannot find (a) the right one or (b) any examples of how to use a module to do what I want.

Can anyone help? I appreciate any help you wise old sages can offer.


Replies are listed 'Best First'.
Re: Checking for multiple instances
by radiantmatrix (Parson) on Sep 24, 2004 at 18:08 UTC
    Depending on your specific requirements, use one of
    • Proc::PID_File - takes care of PID file use for you.
    • Proc::PID::File - OO way to do the above
    • Linux::PID - for managing multi-threaded applications' PPID's on Linux (you still have to deal with files yourself).
    CPAN is a wonderful thing, yes? There are also a number of pid server daemons that can track these types of things well, and Perl modules to talk to them. Or, you can solve the problem in your cron script with the insanely simple:
    #!/bin/bash if (ps ax |grep -q "my_perl_script_name") ; then exit; fi my_perl_script_name
    require General::Disclaimer;

    All code, unless otherwise noted, is untested

    "All it will give you though, are headaches after headaches as it misinterprets your instructions in the most innovative yet useless ways." - Maypole and I - Tales from the Frontier of a Relationship (by Corion)

Re: Checking for multiple instances
by Random_Walk (Prior) on Sep 24, 2004 at 17:47 UTC

    I make my scripts write out their PID to a file when they start after they have checked they are unique. The check consists of seeing if the pid file exists, reading it and checking if the process on that PID looks like an instance of my script (just in case the OS re-used the pid for something else) clean exit will clear up the pid file. Here is the check...

    # See if I am already running # $my_name was derived earlier from $0 # $pidfile is set up in the scripts headers if (-f $pidfile) { open PID, $pidfile; my $pid = <PID>; close PID; print "read pid $pid\n" if $debug; open PROCS, "ps -ef |"; <PROCS>; # loose the header while (<PROCS>) { (undef, my $this_pid) = split; if ($this_pid == $pid) { print "pid in use $_\n"; # check this realy is us, not pid re-use by OS last unless /$my_name/; die "looks like an instance is already running, exiting\n" +; } } } open PID, ">$pidfile"; print PID $$; close PID;

    That is the framework I use, it is a cut and paste from a larger script so will not run in isolation, sorry it is Friday and I want to go home so I can pack for my sailing holiday that starts tomorrow SEG


•Re: Checking for multiple instances
by merlyn (Sage) on Sep 24, 2004 at 19:31 UTC
    My favorite trick is ensuring that the file contains __END__, and then flocking DATA, which is open on the program file itself. No need to create a sentinel file that way.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      That is very cool. Not to pester but would you give a snippet (or point to one) showing it in action?

        I can't find my working example right now, but from memory, something like this:
        #!/usr/bin/perl use Fcntl qw(LOCK_EX LOCK_NB); flock DATA, LOCK_EX | LOCK_NB or die "Already executing!"; ... rest of code ... # do not remove this __END__! __END__

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.

Re: Checking for multiple instances
by dragonchild (Archbishop) on Sep 24, 2004 at 17:06 UTC
    Try having the script check for a running instance of itself as its first task. 'ps' is your friend here. I'm sure there's a CPAN that will do this for you.

    Otherwise, what's wrong with using something like Cache::File? First thing you do is check the cache to see if the lock is set. If it is, leave. If it's not, set the lock. When you're done, release the lock.

    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

    I shouldn't have to say this, but any code, unless otherwise stated, is untested

Re: Checking for multiple instances
by TedPride (Priest) on Sep 24, 2004 at 19:41 UTC
    $0 should give the path to the script, unless it's implemented differently in various verions of Perl? You can use this to create a lock file and lock it (/path/, then check for a lock every time you start the script. The following should work unless the cron job takes longer than two additional cron calls (flock waits forever until it can lock the file itself), and you can easily modify the routines to exit if the lock file exists.
    $fh1 = &file_lock("$folder/index.html"); &file_unlock($fh1); sub file_lock { my $fhandle; my $fpath = (shift) . '.lock'; open($fhandle, ">$fpath"); flock($fhandle, 2); return [$fhandle, $fpath]; } sub file_unlock { my $inp = shift; my ($fhandle, $fpath) = @$inp; flock($fhandle, 8); close($fhandle); unlink($fpath); }

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://393593]
Approved by Arunbear
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2020-10-20 06:28 GMT
Find Nodes?
    Voting Booth?
    My favourite web site is:

    Results (209 votes). Check out past polls.