병렬로 실행되는 bash 스크립트와 함께 잠금 파일 기능을 사용하고 싶습니다. 문제는 아래 스크립트의 함수에서 첫 번째 잠긴 함수를 바로 다시 호출하면 기아 현상이 발생할 수 있다는 점입니다. lockfile
폴링 시간 초과가 다른 프로세스가 잠금을 획득할 수 있을 만큼 충분히 큰 것 같습니다 .
정말? 그렇다면 우리는 어떻게 대처해야 할까요?
lockfile test.lock
echo "TESTING $$"
sleep 10
rm test.lock
예를 들어:
두 개의 셸:
SH1과 SH2가 함께 스크립트를 실행하고
SH1이 잠금을 획득하고 SH2가 차단됩니다.
문제:
SH1이 잠금을 완료하고 제거해도 SH2는 여전히 차단되며(약 1초 동안...) SH1이 스크립트를 반복하면 SH2가 영구적으로 차단됩니다.
답변1
잠금 파일을 찌르면 잠자기 상태가 되지 않으므로 잠금 파일을 tmpfs에 넣어야 합니다.
여기에는 두 가지 해결책이 있습니다.
일부 프로세스에는 정적 수면으로 충분합니다.
WAIT=5 # max seconds between two procs; larger is nicer for the system
lockfile -${WAIT} -r-1 "${LOCKFILE}"
## payload
rm -f "${LOCKFILE}"
# sleep outside the lock for at least $WAIT seconds
# to give another proc a chance to lock it
sleep ${WAIT}s
무작위 수면은 많은 프로세스를 처리하지만 매우 좋지는 않습니다.
MAX=5
MIN=3
WAIT=$((MIN+RANDOM/(1+MAX-MIN))) # random sleep between min and max
lockfile -${WAIT} -r-1 "${LOCKFILE}"
## payload
rm -f "${LOCKFILE}"
# sleep outside the lock for at least $WAIT seconds
# to give another proc a chance to lock it
sleep ${WAIT}s
웨이터는 지속 시간이 길어질수록 많은 프로세스에 적합해집니다.
MAX=600
MIN=1
WAIT=${MAX} # max seconds between two procs; larger is nicer
while ! lockfile -r0 "${LOCKFILE}"
do
sleep ${WAIT}s
WAIT=$(( WAIT / 2 )) # backoff formula
if [ ${WAIT} -lt ${MIN} ]; then
WAIT=${MIN}
fi
done
## payload
rm -f "${LOCKFILE}"
# reduced WAIT means likely to run again; alternatively use MAX
sleep ${WAIT}s
답변2
문제가 있는지 잘 모르겠습니다.
이것fs/locks.c의 커널 코드다음 설명이 포함되어 있습니다.
519 /* Insert waiter into blocker's block list.
520 * We use a circular list so that processes can be easily woken up in
521 * the order they blocked. The documentation doesn't require this but
522 * it seems like the reasonable thing to do.
523 */
아직도 이것을 믿을 수 없다면 유일한 합리적인 선택은 세마포어를 사용하는 것입니다.semop(2), semget(2).