#!/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