【发布时间】:2018-11-18 00:31:17
【问题描述】:
显然 POSIX 声明
文件描述符或流在 打开它所引用的文件描述;打开的文件描述 可能有几个手柄。 […] 应用程序的所有活动 影响第一个句柄上的文件偏移量应暂停 直到它再次成为活动文件句柄。 […] 手柄需要 不在同一过程中适用这些规则。 -- POSIX.1-2008
和
如果两个线程各自调用 [write() 函数],则每次调用应 要么看到另一个调用的所有指定效果,要么没有 其中。 -- POSIX.1-2008
我对此的理解是,当第一个进程发出一个
write(handle, data1, size1) 和第二个进程问题
write(handle, data2, size2),写入可以按任何顺序发生,但
data1 和 data2 必须既原始又连续。
但是运行下面的代码给了我意想不到的结果。
#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);
}
我尝试在 Linux 和 Mac OS X 10.7.4 上运行它并使用 grep -a
'^[^-]\|^..*-' /tmp/atomic-write.log 表明某些写入不是
连续或重叠 (Linux) 或完全损坏 (Mac OS X)。
在open(2) 调用中添加标志O_APPEND 可以解决此问题
问题。很好,但我不明白为什么。 POSIX 说
O_APPEND 如果设置,则文件偏移量应设置为每次写入之前的文件末尾。
但这不是这里的问题。我的示例程序从来没有
lseek(2) 但共享相同的文件描述和相同的文件
偏移量。
我已经在 Stackoverflow 上阅读过类似的问题,但它们仍然存在 不要完全回答我的问题。
Atomic write on file from two process 没有具体说明 解决进程共享相同文件描述的情况 (而不是同一个文件)。
How does one programmatically determine if “write” system call is atomic on a particular file? 这么说
POSIX 中定义的
write调用根本没有原子性保证。
但作为cited above,它确实有一些。更重要的是,
O_APPEND 似乎触发了这种原子性保证,尽管看起来
对我来说,即使没有O_APPEND,这个保证也应该存在。
您能否进一步解释这种行为?
【问题讨论】:
-
OSX 是否声称符合 POSIX08?我不这么认为。 (我相信他们只声称 '03 合规。)
-
好点,根据images.apple.com/macosx/docs/OSX_for_UNIX_Users_TB_July2011.pdf,它是“Open Brand UNIX 03”。我得看看这是什么意思。
-
很多人会根据 08 年前的规则进行回答,其中写入只是管道上的原子操作,即使在某些条件下也是如此。许多平台仍然不支持 '08 语义。许多声称拥有的平台仍然有一个或多个没有的文件系统。
-
OSX 声称的“POSIX 一致性”都是谎言。他们所拥有的是认证(这基本上是花很多钱并通过一些简单的测试,除了最明显的不合格案例之外什么都没有发现),这并不能保证,并且不可能保证符合规范;后者唯一能做的就是正式证明,对于如此庞大的系统来说,这基本上是不可能的。
-
话虽如此,发布一致性认证的 Open Group 和其他标准机构确实应该采用撤销程序,即如果已通过认证的实现可以证明不符合规范,并拒绝延长一段时间(比如 6 个月或 1 年)补救这种情况,认证会自动被撤销。
标签: c file-io posix multiprocessing