我正在尝试以以下方式配置脚本
从here那里我发现了一个非常不错的羊群例子:
exec 200>$pidfile
flock -n 200 || exit 1
pid=$$
echo $pid 1>&200
如果无法获取锁(-n标志),则失败。
我是否可以假定这意味着另一个文件已锁定$pidfile
,并且如何检测到该锁定已在其他过程中释放?
我知道wait $pid
会等到该过程完成为止,因此,如果有某种方法可以记录当前哪个进程持有锁,或者只是检测到解锁,以便其他进程知道数据可用,那么我认为这会起作用。
有什么想法吗?
答案 0 :(得分:0)
答案 1 :(得分:0)
我的解决方案使用两个文件pid.temp和data.temp:
backgroundGetData() {
local data=$1
# if global is null, check file.
if [ -z "$data" ]; then
data=$( cat $DATA_TEMP_FILE 2>/dev/null )
fi
# if file is empty, check process is making the request
if [ -z "$data" ]; then
for i in {1..5}; do
echo "INFO - Process: $BASHPID - Attempting to lock data temp file" >&2
local request_pid=$( cat $PID_FILE 2>/dev/null )
if [ -z "$request_pid" ]; then request_pid=0; fi
local exit_code=1
if [ "$request_pid" -eq 0 ]; then
( flock -n 200 || exit 1
echo "INFO - Process: $BASHPID - Fetching data." >&2
echo "$BASHPID">"$PID_FILE"
getData > $DATA_TEMP_FILE
) 200>$DATA_TEMP_FILE
exit_code=$?
fi
echo "INFO - Process: $BASHPID - returned $exit_code from lock attempt.">&2
[ $request_pid -ne 0 ] && echo "INFO - Process: $BASHPID - $request_pid is possibly locking">&2
if [ $exit_code -ne 0 ] && [ $request_pid -ne 0 ]; then
echo "INFO - Process: $BASHPID - waiting on $request_pid to complete">&2
tail --pid=${request_pid} -f /dev/null
echo "INFO - Process: $BASHPID - finished waiting.">&2
break
elif [ $exit_code -eq 0 ]; then break;
else
sleep 2
fi
done
data=$( cat $DATA_TEMP_FILE )
if [ -z "$data" ]; then
echo "WARN - Process: $BASHPID - Failed to retrieve data.">&2
fi
fi
echo "$least_loaded"
}
它可以像这样使用:
DATA=""
DATA_TEMP_FILE="data.temp"
PID_FILE="pid.temp"
$( backgroundGetData $DATA ) & ## Begin making request
doThing() {
if [ -z $DATA ]; then
# Redirect 3 to stdout, then use sterr in backgroundGetData to 3 so that
# logging messages can be shown and output can also be captued in variable.
exec 3>&1
DATA=$( backgroundGetData $DATA 2>&3)
fi
}
for job in "$jobs"; do
doThing &
done
它对我有用,尽管我不确定100%的安全性。