synchronize 1.7 KB

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