Linux 锁文件饥饿

Linux 锁文件饥饿

我想对并行运行的 bash 脚本使用锁定文件功能。问题是,在下面脚本中的功能中,如果立即再次调用第一个锁定的函数,则可能会发生饥饿。看起来lockfile轮询的超时时间足够大,以允许其他进程获取锁。

真的吗?那应该如何处理呢?

lockfile test.lock
echo "TESTING $$"
sleep 10
rm test.lock

例如:

两个 shell :
SH1、SH2 一起运行脚本,
SH1 获取锁,SH2 被阻止。
问题:
当 SH1 完成并移除锁时,SH2 仍然被阻止(大约一秒钟......),如果 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)

相关内容