问题描述
显然POSIX指出
and
My understanding of this is that when the first process issues awrite(handle, data1, size1)
and the second process issueswrite(handle, data2, size2)
, the writes can occur in any order butthe data1
and data2
must be both pristine and contiguous.
But running the following code gives me unexpected results.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
die(char *s)
{
perror(s);
abort();
}
main()
{
unsigned char buffer[3];
char *filename = "/tmp/atomic-write.log";
int fd, i, j;
pid_t pid;
unlink(filename);
/* XXX Adding O_APPEND to the flags cures it. Why? */
fd = open(filename, O_CREAT|O_WRONLY/*|O_APPEND*/, 0644);
if (fd < 0)
die("open failed");
for (i = 0; i < 10; i++) {
pid = fork();
if (pid < 0)
die("fork failed");
else if (! pid) {
j = 3 + i % (sizeof(buffer) - 2);
memset(buffer, i % 26 + 'A', sizeof(buffer));
buffer[0] = '-';
buffer[j - 1] = '\n';
for (i = 0; i < 1000; i++)
if (write(fd, buffer, j) != j)
die("write failed");
exit(0);
}
}
while (wait(NULL) != -1)
/* NOOP */;
exit(0);
}
I tried running this on Linux and Mac OS X 10.7.4 and using grep -a'^[^-]\|^..*-' /tmp/atomic-write.log
shows that some writes are notcontiguous or overlap (Linux) or plain corrupted (Mac OS X).
Adding the flag O_APPEND
in the open(2)
call fixes thisproblem. Nice, but I do not understand why. POSIX says
but this is not the problem here. My sample program never doeslseek(2)
but share the same file description and thus same fileoffset.
I have already read similar questions on Stackoverflow but they stilldo not fully answer my question.
Atomic write on file from two process does not specificallyaddress the case where the processes share the same file description(as opposed to the same file).
How does one programmatically determine if "write" system call is atomic on a particular file? says that
But as cited above it does have some. And what’s more,O_APPEND
seems to trigger this atomicity guarantee although it seemsto me that this guarantee should be present even without O_APPEND
.
Can you explain further this behaviour ?
man 2 write
on my system sums it up nicely:
Here is a quote from a recent discussion on the ext4
mailing list:
This is a clear indication that ext4
-- to name just one modern filesystem -- doesn't conform to POSIX.1-2008 in this respect.
这篇关于写的`原子性(2)`到本地文件系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!