[ Perl tips index ]
[ Subscribe to Perl tips ]
Imagine the situation where we have a faxmodem connected to our machine, and a program that sends a fax to its destination. In this situation we only want a single instance of the program running at any time, since the faxmodem can only be sending a single fax at a time.
The problem of ensuring that only a single process is running is a common one. Today we'll investigate a simple solution to solve the problem in Perl.
Perl comes with a portable locking mechanism called flock, which is
short for file-lock. Using flock we can apply advisory locks
to any filehandle:
use Fcntl qw(:flock);
flock(FILE1, LOCK_EX) or die "Cannot lock - $!"; # Exclusive lock
flock(FILE2, LOCK_SH) or die "Cannot lock - $!"; # Shared lock
The use Fcntl qw(:flock) line simply imports the LOCK_EX,
LOCK_SH and a few other constants for our use. Once we've
done that, we can ask for either exclusive or shared locks on our
filehandles.
Perl's flock mechanism can be used to lock any filehandle,
including sockets and streams like STDIN. If the lock fails,
or your operating system does not support locking on the requested
filehandle, flock will return false.
By default, flock will wait indefinitely until a lock is obtained,
however we can request a lock be made in a non-blocking fashion
by using the special constant LOCK_NB:
use Fcntl qw(:flock);
flock(FILE, LOCK_EX|LOCK_NB) or die "Cannot lock - $!";
While Perl allows us to unlock files by using the LOCK_UN operation,
this happens automatically when a file is closed. Closing a file
is the preferred way to unlock it, as it ensures that not only locks
and resources are released, but also that we cannot accidently access
or write to the file after it has been unlocked.
It's common to see external lockfiles being used to ensure that only a single instance of a program is running on a machine. This has the additional overhead of creating and tidying up the lockfile. Luckily for us, this is rarely needed in Perl.
We can take advantage of the fact that our program's source code
will be stored in a file, and that file must be accessible to the
Perl interpreter in order for it to run. Rather than locking an
external file, we can simply lock our own source code, the filename
of which can be found in the special variable $0.
use Fcntl qw(:flock);
open(SELF,"<",$0) or die "Cannot open $0 - $!";
flock(SELF, LOCK_EX|LOCK_NB) or die "Already running.";
Perl programs also allow data to be stored at the end of their
source code, a special __DATA__ section. If this exists, the
data is accessible through a special filehandle called DATA.
We can use this as an alternative method to lock our own program.
use Fcntl qw(:flock);
flock(DATA, LOCK_EX|LOCK_NB) or die "Already running.";
# ...
__DATA__
This achieves the same effect as the previous example without having to
open the program file. One major drawback is that the
__DATA__ section must appear at the bottom of your code and is therefore
often a long way away from your locking code. This distance is a potential
source of bugs. Should the __DATA__
section be accidently deleted, or should you forget to add it, the flock
will fail and the program will terminate with your die message. In this
case, we'd be told that the program was already running, not that
__DATA__ didn't exist to be locked!
For more coverage on using flock,
the slides from Mark Jason Dominus' File Locking Tricks and Traps make
excellent reading. They can be found at
http://perl.plover.com/yak/flock/ .
[ Perl tips index ]
[ Subscribe to Perl tips ]
| Location | Course | Course Date | Duration | Early Bird Date |
|---|---|---|---|---|
| Sydney | Programming Perl | Mon 22 Mar 2010 | 5 days | — |
| Brisbane | Programming Perl | Mon 12 Apr 2010 | 5 days | — |
| Canberra | Programming Perl | Mon 19 Apr 2010 | 5 days | — |
| Melbourne | Programming Perl | Mon 16 Aug 2010 | 5 days | Mon 12 Jul 2010 |
| Sydney | Programming Perl | Mon 6 Sep 2010 | 5 days | Tue 3 Aug 2010 |
| Canberra | Programming Perl | Mon 20 Sep 2010 | 5 days | Tue 24 Aug 2010 |
For future dates, please see our training calendar.
This Perl tip and associated text is copyright Perl Training Australia. You may freely distribute this text so long as it is distributed in full with this Copyright noticed attached.
If you have any questions please don't hesitate to contact us:
| Email: | contact@perltraining.com.au |
| Phone: | 03 9354 6001 (Australia) |
| International: | +61 3 9354 6001 |
Copyright 2001-2009 Perl Training Australia. Contact us at contact@perltraining.com.au