如何在多进程系统中实现锁定?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在多进程系统中实现锁定?相关的知识,希望对你有一定的参考价值。
我们并行运行了很多jenkins项目。我们正在使用python,我们选择使用pyenv管理虚拟环境。不幸的是,pyenv有一个着名的race condition。要解决此问题,我想在进程级别实现锁定。我想做的是:
lock some resource (a file?)
do my pyenv stuff
unlock the resource
我的脚本是用bash编写的。如何在bash中实现资源锁定/解锁?
答案
因此,想要跨进程锁定的unix世界中的朋友是一个名为flock
的命令。它在操作系统级别实现为原子操作,对于此类事物非常有用。你可以阅读more about it here。以下是如何使用它:
# Wait for lock on (fd 222) for 10 seconds
(flock -w 10 222 || exit 1
{
# Do the operations you want to here
}) 222>/path/to/lockfile
这里有几个技巧。首先,通常在使用输出重定向时,bash会在尝试flock之前先打开一个文件。但是,在这里,因为我们有()
bash将首先启动一个第一个命令为flock的子shell。 flock将尝试获取文件句柄222上的锁。然后,Flock将锁定文件描述符。锁定文件描述符后,将运行{}
中的代码。在运行之后,文件描述符222的内容被写入锁文件(即,什么都没有),文件被关闭并且锁被释放。这就像关闭文件释放锁的C一样。当然,没有解释它比杰出的@CharlesDuffy(帽子提示@codeforester)更好地解释here上发生了什么。
另一答案
我会考虑使用符号链接而不是常规文件 - 因为,符号链接创建是一个原子操作。所以,我们可以这样做:
lockfile=/path/to/lock.file
# lockfile is a symlink that points the string that holds the PID of the locking process
ln -s $$ $lockfile 2>/dev/null
if [[ $? == 0 ]]; then
# got the lock - ln -s will fail if symlink exists already
else
otherprocess=$(readlink $lockfile)
if [[ $otherprocess != $$ ]]; then
ps -p $otherprocess 2>/dev/null
if [[ $? != 0 ]]; then
# stale lock; remove and lock again
# this can result in race conditions
# probably, we can make the lock procedure as a function that is shared by concurrent bash scripts and have a random sleep before we remove the stale lock and proceed
fi
fi
fi
以上是关于如何在多进程系统中实现锁定?的主要内容,如果未能解决你的问题,请参考以下文章
以下 C++ 代码中实现的 DCL(双重检查锁定)是不是是线程安全的?