我使用flock()来实现进程间命名互斥(即某个进程可以决定锁定“some_name”,这是通过锁定临时目录中名为“some_name”的文件来实现的:
lockfile = "/tmp/some_name.lock";
fd = open(lockfile, O_CREAT);
flock(fd, LOCK_EX);
do_something();
unlink(lockfile);
flock(fd, LOCK_UN);
应在某个时候删除锁定文件,以避免用数百个文件填充临时目录。
然而,这段代码中存在明显的竞争条件;进程 A、B 和 C 的示例:
A opens file
A locks file
B opens file
A unlinks file
A unlocks file
B locks file (B holds a lock on the deleted file)
C opens file (a new file one is created)
C locks file (two processes hold the same named mutex !)
有没有办法在某个时刻删除锁定文件而不引入这种竞争条件?
抱歉,如果我回答一个死问题:
锁定文件后,打开它的另一个副本,fstat 两个副本并检查 inode 号,如下所示:
lockfile = "/tmp/some_name.lock";
while(1) {
fd = open(lockfile, O_CREAT);
flock(fd, LOCK_EX);
fstat(fd, &st0);
stat(lockfile, &st1);
if(st0.st_ino == st1.st_ino) break;
close(fd);
}
do_something();
unlink(lockfile);
flock(fd, LOCK_UN);
这可以防止竞争条件,因为如果一个程序对仍在文件系统上的文件持有锁定,则具有剩余文件的每个其他程序都将具有错误的索引节点号。
我实际上在状态机模型中使用以下属性证明了这一点:
如果 P_i 在文件系统上锁定了一个描述符,则临界区中没有其他进程。
如果 P_i 位于具有正确 inode 的 stat 之后或位于关键部分,则它的描述符已锁定在文件系统上。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)