最近,我一直在环境AIX 7.1上观察一些有趣的东西。为了追踪这个问题,我在Java中创建了一个小型锁定应用程序:
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
public class Locker {
public static void main(String[] args) throws Exception {
File file = new File("/etc/passwd");
FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
FileLock lock;
try {
lock = channel.tryLock();
if (lock != null) {
System.out.println("I have the lock");
while(true) {}
}
} catch (OverlappingFileLockException e) {
e.printStackTrace();
}
}
}
据我所知,这会在/ etc / passwd上获得读写锁定。如果我尝试运行此应用程序的两个实例,我只能按预期在一个实例中获取锁定。同样,如果我运行此命令:
su user2 -c echo test
该命令一直挂起,直到我从Java应用程序中释放锁定。另一方面,用:
读取文件cat /etc/passwd
成功运行。甚至用以下内容写入文件:
cat /etc/passwd > /etc/passwd
也很好。现在,显然Java FileLock实现依赖于系统,并且由于这种性质,没有指定的行为。然而,我很好奇的是为什么'su'需要等待。是否有可能'cat'重定向只是删除文件并使用新输出重新创建它,或者这只是锁定机制在命令之间不一致的情况?
编辑:由于提出问题我向Java应用程序添加了一些写语句,因此程序的结构如下:
Acquire Java Lock on /etc/passwd
IO-Redirect with a small change to /etc/passwd
Append some text to /etc/passwd in the Java application
所有这些信息都反映在更新的/ etc / passwd中,因此看起来IO重定向不仅仅是删除文件。因此,为什么'su'和'>'之间存在差异(可能还有很多其他的东西)?
答案 0 :(得分:2)
UNIX上的文件锁定是建议性的,不是强制性的。也就是说,锁完全独立于任何试图读取或写入文件的人都没有影响。它只与试图获取锁的其他程序交互。
由于cat
和重定向不会尝试锁定文件,因此锁定对它们没有影响。另一方面,su
在读取它之前锁定/ etc / passwd,因此持有锁的程序会使它等待(获取锁),直到你释放它为止。