1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
#!/bin/sh
# %W% %@% Copyright (c) 1998 Larry McVoy.
#
# Usage: SYNC_PID=3 SYNC_MAX=20 synchronize /tmp/sync_dir
#
# Used to sync up a bunch of processes so that they can operate in lockstep
# as much as possible.
#
# The first process to try and sync will mkdir(pathname) and create a named
# pipe in the directory. It also creates a file, pathname/$PID where pid
# is not the process id, it is the process number. The group of processes
# must be numbered from 1..N and they must each know their number. The Nth
# process is the master. Whereas all the other processes block, opening the
# pipe, the master spins in a loop, waiting for pathname/1 .. pathname/N-1
# to show up in the directory. When they are all there, the master opens
# the pipe for writing and all the other processes get woken up and leave.
#
# It is outside of this program, but the directory must not exist before the
# synchronization. So you typically rm -rf it well before trying to sync.
if [ X$1 = X ]; then echo "Usage: $0 pathname"; exit 1; fi
if [ X$SYNC_PID = X ]; then echo "Must set SYNC_PID"; exit 1; fi
if [ X$SYNC_MAX = X ]; then echo "Must set SYNC_MAX"; exit 1; fi
DIR=$1
mkdir -p $DIR 2>/dev/null
if [ ! -e $DIR/fifo ]
then mkfifo $DIR/fifo 2>/dev/null
chmod 666 $DIR/fifo 2>/dev/null
fi
# slaves just read the pipe
if [ $SYNC_PID != $SYNC_MAX ]
then touch $DIR/$SYNC_PID
read x < $DIR/fifo
exit 0
fi
# Master waits for all the other processes to get there
PIDS=""
I=1
while [ $I -lt $SYNC_MAX ]
do PIDS=" $I$PIDS"
I=`expr $I + 1`
done
while true
do GO=Y
for s in $PIDS
do if [ ! -e $DIR/$s ]
then GO=N
fi
done
if [ $GO = Y ]
then # This assumes that all the processes will
echo sleep 2 > $DIR/fifo &
exit 0
fi
msleep 250
done
|