| Within a shellscript you could try
trap 'rm $LOCK_FILE' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
:
:
Do some processing
:
:
while [ -f $LOCK_FILE ] # Sleep while another process running
do
LOCK_PID=LOCK_PID=`cat $LOCK_FILE`
if ps -eaf | grep $LOCK_PID | grep -v grep > /dev/null 2>&1
then
sleep 10 # Process still running
else
break # Process no longer running
fi
done
echo $$ > $LOCK_FILE # Lock out other processes
:
:
Do bit that can only be done one at a time
:
:
rm $LOCK_FILE
Obviously, this is by no means infallible...if your unlucky in the
timing you may get more than one process breaking out of the while loop
& trying to do the processing at the same time, but I expect it's the
best you'll get, unless you perform a secondary check that the PID of
the running process matches that contained in the LOCK_FILE.
Brendan
|
| >> if you're unlucky
Could you reduce the 'unluckiness' window by setting noclobber and looping round
again if the write to the lockfile failed?
In fact, I think you can simplify the locking code to (using ksh):
set -C
# pre-processing
...
# take out exclusive lock
(while ! echo $$ > LCKFILE; do # Loop while we can't create the lockfile
if ! ps -p $(<LCKFILE); then
rm LCKFILE # Remove file if owning process has died
else
sleep 1
done) 2> /dev/null # Discard shell errors if can't write to file
# do bit that can only be done one at a time
...
# free lock
rm LCKFILE
# do some post-processing
...
Of course, as this uses a world-writeable lock file, it relies on everyone
cooperating and playing by the rules. Also, this doesn't guarantee FIFO
operation if two or more processes are waiting on the lock; you'd need a more
sophisticated queueing system to do that.
For example, successive processes could append their PIDs to the file when they
wait on the lock. Then, to release the lock the holding process just removes
its PID, rather than deleting the file. This signals to the waiting processes
that the lock is free, but only the process next-in-line is allowed to take the
lock, bumping all the others one up the queue at the same time.
Finally, I don't know how 'atomic' the shell's test-and-set action around
redirection-with-noclobber is, so there's still probably a window of opportunity
for this to fail. If this is really important, you might want to knock-up a
trivial C program to implement a guaranteed lock mechanism with creat(2) or
proper semaphores.
Scott
|