[英]How To Append To File in C, using Open in O_APPEND Mode on linux?
[英]Open file with O_APPEND on FreeBsd and Linux doesn't look like an atomic operation?
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#define BUFSIZE 1024*1024*100
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
int main()
{
pid_t pid;
int pfd = open("data.txt", O_CREAT|O_RDWR|O_TRUNC|O_APPEND, FILE_MODE);
if ((pid = fork()) < 0)
{
printf("errr fork\n");
exit(0);
} else if (pid == 0)
{
int cfd = open("data.txt", O_CREAT|O_RDWR|O_TRUNC|O_APPEND, FILE_MODE);
for (int i = 0; i < 1000000; ++i)
if (write(cfd, "child\n", 6) == -1)
{
printf("err in child\n");
exit(0);
}
exit(0);
}
for (int i = 0; i < 1000000; ++i)
if (write(pfd, "parent\n", 7) == -1)
{
printf("error in parent\n");
exit(0);
}
return 0;
}
测试环境1:
优名
FreeBSD freebsd 10.0-RELEASE-p12 FreeBSD 10.0-RELEASE-p12#0:星期二11月4日05:07:17 UTC 2014 root@amd64-builder.daemonology.net:/ usr / obj / usr / src / sys / GENERIC amd64
lang -v
FreeBSD clang版本3.3(tags / RELEASE_33 / final 183502)20130610目标:x86_64-unknown-freebsd10.0线程模型:posix
测试环境2:
优名
Linux debian 3.2.0-4-amd64#1 SMP Debian 3.2.63-2 + deb7u1 x86_64 GNU / Linux
gcc --version
gcc(Debian 4.7.2-5)4.7.2版权所有(C)2012自由软件基金会,公司。 请参阅复制条件的来源。 没有保修; 甚至不是出于适销性或针对特定目的的适用性。
有些线丢了
$ sort data.txt | uniq -c
1000000 child
982937 parent
O_APPEND似乎没有按照手册页中的说明工作。
谁能给我更多有关此的信息?
问题在于,当子级打开文件时,它将被截断,丢失了父级已写入文件的数据,从而使父级的计数减少了。 由于孩子必须第二次打开文件,并且文件打开是一项昂贵的操作,因此它可能永远是计数少的父级。 如果将第一个打开位置移动到只有父打开位置,则时间会有所不同; 有时孩子的条目可能会更少。
修改后的代码:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
int main(void)
{
pid_t pid;
int pfd = open("data.txt", O_CREAT | O_RDWR | O_TRUNC | O_APPEND, FILE_MODE);
if ((pid = fork()) < 0)
{
printf("errr fork\n");
exit(0);
}
else if (pid == 0)
{
int cfd = open("data.txt", O_CREAT | O_RDWR | O_TRUNC | O_APPEND, FILE_MODE);
for (int i = 0; i < 1000000; ++i)
{
char buffer[32];
snprintf(buffer, sizeof(buffer), "child%07d\n", i);
if (write(cfd, buffer, strlen(buffer)) == -1)
{
printf("err in child\n");
exit(0);
}
}
}
else
{
for (int i = 0; i < 1000000; ++i)
{
char buffer[32];
snprintf(buffer, sizeof(buffer), "parent%07d\n", i);
if (write(pfd, buffer, strlen(buffer)) == -1)
{
printf("error in parent\n");
exit(0);
}
}
}
return 0;
}
一次运行它时,输出开始:
parent0000052
parent0000053
parent0000054
parent0000055
parent0000056
parent0000057
parent0000058
parent0000059
parent0000060
parent0000061
parent0000062
parent0000063
parent0000064
child0000000
parent0000065
child0000001
parent0000066
child0000002
parent0000067
因此,父级在子级截断文件(0..51)之前已执行52次写入。 计数同意:
$ grep -o -E 'child|parent' data.txt | sort | uniq -c
1000000 child
999948 parent
$
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.