Alister West

home is where your code is ...

Script file locking

There are many ways to lock a process in perl... this is my list.

Lazy::Lockfile

# Simple object creation - cleans itself up on destroy.
use Lazy::Lockfile
my $lockfile = Lazy::Lockfile->new( $pid_file ) || die "Couldn't get lock!";

File::Lockfile

# Uses the singleton pattern.
use File::Lockfile
my $lockfile = File::Lockfile->new( basename($0)."pid", "$home/logs" );
if ( my $pid = $lockfile->check ) {
    $DEBUG and say "It looks like $0 is already running with PID: $pid";
    exit;
}
$lockfile->write;
...
END { $lockfile->remove; } # ick

IPC::ConcurrencyLimit

use IPC::ConcurrencyLimit;
# basic example uses flock.
# can do db backends for multi-server locks.

sub run {
    # lock released when $limit goes out of scope
    my $limit = IPC::ConcurrencyLimit->new(
        max_procs => 1,
        path      => '/var/run/myapp',
    );

    my $id = $limit->get_lock
     or warn "Process already running. Exiting." && exit;

    { ... } 
}
run();

flock DATA

# Use global file-handler DATA for this process to lock processing.
# http://www.perlmonks.org/?node_id=590619    
# Not portable (but works on Linux)

use Fcntl qw(:flock);
print "$$ - start\n";
unless (flock(DATA, LOCK_EX|LOCK_NB)) {
    print "$$ - $0 is already running. Exiting.\n";
    exit(1);
}
print "$$ - doing stuff ...\n";
sleep(10);
print "$$ - end\n";
__DATA__
DO NOT REMOVE - NEEDED FOR FLOCK

flock DATA - with waiting

# Lock script on global fh DATA - but introduce some waiting to pretend to
# be a single threaded process.  Have used for an admin.cgi process where
# apache has multiple children but admin can only do one thing at once

use Fcntl qw/:flock/;
warn "$$ - Start\n";
my $ret = eval {
    local $SIG{ALRM} = sub { die "timeout\n" };
    alarm(10);
    flock(DATA, LOCK_EX);
    1;
};
alarm(0); # reset
if (!$ret) {
    print $@ eq "timeout\n" ? "Process is busy!\n" : "Error getting lock: $!";
    exit(1);
}
warn "$$ - doing stuff ...\n";
sleep 10;
warn "$$ - end\n";
__DATA__
DO NOT REMOVE - NEEDED FOR FLOCK
By Alister West