Unix 中的移动操作是原子操作吗?
假设有 2 个进程 P1 和 P2,并且它们访问共享文件 。Foo.txt
假设 P2 正在读取 。我不希望P1在P2阅读时写入它。Foo.txt
Foo.txt
所以我认为我可以让P1写入,作为最后一步,重命名为。我的编程语言是JavaFoo.tmp
Foo.tmp
Foo.txt
所以我的问题是,这是否能确保P2从中读取正确的数据?P2 完成读取文件后,是否会提交重命名操作?Foo.txt
编辑
我试图按如下方式重新创建此方案:
我的P1代码是这样的:
File tempFile = new File(path1);
File realFile = new File(path2);
BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));
for(int i=0;i<10000;i++)
writer.write("Hello World\n");
writer.flush();
writer.close();
tempFile.renameTo(realFile);
我的P2代码是:
BufferedReader br = new BufferedReader(new FileReader(file));
String line = null;
while(true) {
while((line=br.readLine())!=null){
System.out.println(line);
Thread.sleep(1000);
}
br.close();
}
我的示例共享文件:
Test Input
Test Input
Test Input
我几乎同时启动P1和P2(P2首先启动)。
因此,根据我的理解,即使P1已经编写了一个新的Foo.txt,由于P2已经在阅读它,它应该读取旧的Foo.txt内容,直到它重新打开缓冲阅读器到Foo.txt。
但实际上发生的事情是P2读取三次,正如输入所期望的那样,但之后它读取由P1编写的新内容。Test Input
P2 输出:
Test Input
Test Input
Test Input
Hello World
Hello World
Hello World
.
.
.
所以它不能正常工作。我是否错误地测试了此方案?我觉得我错过了一些东西。