In general, it's advisable to lock the resources
your program is working on, not the program itself. Think
about the consequencies in case of abnormal termination and
so on.
Anyway, There's More Than One Way To Do It. The most
straightforward is probably using a wrapper, that is,
a pprogram that does some housekeeping before calling the actual one.
I'd suggest a wrapper and not changing yuor program itself because
changing the program for adding this "feature" needs to be seriously motivated,
in my opinion. Again, I think that locking resources is a cleaner approach.
Unfornutately you can't use perl's flock because
it requires a file to be open in write mode for having an
exclusive lock, and production scripts that can be open in
write mode are not a Good Thing.
So you may resort to a couple of quite common tricks (watch out,
ythey're not immune from race conditions! But most
programmers seem not to care too much about it):
- When the wrapper starts, it checks the process table and
does an exec of the actual program only if not
already in the process table. Very easily accomplished by
a shell script. Not very portable: some systems (I assume UNIX)
want you to type ps auwx, some others ps -ef.
- When the wrapper starts, it checks for the presence of a
file, say /var/run/program_is_running. If the file is
not there, it is immediately created and the actual process is
spawned. When it finishes, the wrapper regains control and
gets rid of /var/run/program_is_running
Both approaches can be implemented with simple shell
scripts, valid in general for every program to be run
in "exclusive" mode. As a side note, this kind of locking
is only advisory! Malicious programs can circumvent it if they want.
If you want to change your code, you can use Perl's flock
in a number of ways, always locking a dummy file, not
the program itself!
For example (untested code):
#!/usr/bin/perl -w
use strict;
open(EXCLUSIVELOCK, ">/tmp/$0.lock");
flock(EXCLUSIVELOCK, LOCK_EX);
# If we reach this point, we have exclusive lock
# The rest of the code goes here, immediately before
# terminating, you can release the lock
flock(EXCLUSIVELOCK, LOCK_UN);
This type of locking is always advisory, but it's
exempt from race conditions.
This should be a good starting point to modify according
to youir needs, for example not timeouts are implemented:
if the file is locked, a second program would wait until
the first has finished. You may want to check the perlfunc
manual page to give an error and exit instead, or implement
timeouts and so on. Happy locking!
-- TMTOWTDI |