下面就是woodie上述思路的一个实现,只是在centos 4.2下简单地测试了一下,可能还有不少错误,请大家帮忙“除虫”。^_^思路上有什么问题也请不吝指教:
脚本1,token.sh,负责令牌管理和死锁检测处理。与下一个脚本一样,为了保持脚本的最大的兼容性,尽量使用Bourne shell的语法,并用printf代替了echo,sed的用法也尽量保持通用性。这里是由一个命名管道接受请求,令牌在一个文件中发出。如果用ksh也许可以用协进程来实现,熟悉ksh的朋友可以试一试。^_^
#!/bin/sh
#name: token.sh
#function: serialized token distribution, at anytime, only a cerntern number of token given out
#usage: token.sh [number] &
#number is set to allow number of scripts to run at same time
#if no number is given, default value is 1
if [ -p /tmp/p-aquire ]; then
rm -f /tmp/p-aquire
fi
if mkfifo /tmp/p-aquire; then
printf "pipe file /tmp/p-aquire createdn" >>token.log
else
printf "cannot create pipe file /tmp/p-aquiren" >>token.log
exit 1
fi
loop_times_before_check=100
if [ -n "$1" ];then
limit=$1
else
# default concurrence is 1
limit=1
fi
number_of_running=0
counter=0
while :;do
#check stale token, which owner is died unexpected
if [ "$counter" -eq "$loop_times_before_check" ]; then
counter=0
for pid in `cat token_file`;do
pgrep $pid
if [ $? -ne 0 ]; then
#remove lock
printf "s/ $pid//nwqn"|ed -s token_file
number_of_running=`expr $number_of_running - 1`
fi
done
fi
counter=`expr $counter + 1`
#
if [ "$number_of_running" -ge "$limit" ];then
# token is all given out. bypass all request until a instance to give one back
pid=`sed -n '/stop/ {s/([0-9]+) +stop/1/p;q}' /tmp/p-aquire`
if [ -n "$pid" ]; then
# get a token returned
printf "s/ $pid//nwqn"|ed -s token_file
number_of_running=`expr $number_of_running - 1`
continue
fi
else
# there is still some token to give out. serve another request
read pid action < /tmp/p-aquire
if [ "$action" = stop ]; then
# one token is given back.
printf "s/ $pid//nwqn"|ed -s token_file
number_of_running=`expr $number_of_running - 1`
else
# it's a request, give off a token to instance identified by $pid
printf " $pid" >> token_file
number_of_running=`expr $number_of_running + 1`
fi
fi
done
--------------------------------------------------------------------------------------------
修订记录:
1.修正token.sh的一个BUG,将原来用sed删除失效令牌的命令用ed命令代替。感谢r2007和waker两位指出错误!
--------------------------------------------------------------------------------------------
脚本2:并发执行的脚本 -- my-script。在"your code goes here"一行后插入你自己的代码,现有的是我用来测试的。
#!/bin/sh # second to wait that the ditributer gives off a token a_while=1 if [ ! -p /tmp/p-aquire ]; then printf "cannot find file /tmp/p-aquiren" >&2 exit 1 fi # try to aquire a token printf "$$n" >> /tmp/p-aquire sleep $a_while # see if we get one grep "$$" token_file if [ $? -ne 0 ]; then # bad luck. :( printf "no token free now, exitting...n" >&2 exit 2 fi










