c代码:fprintf从多个代码到同一个文件
c code: fprintf from multiples codes to the same file
我对 fprintf()
的工作原理有些怀疑。我读到 fprintf()
不能保证对其写入的文件执行原子追加操作。
这在实践中意味着什么?
考虑以下简单情况,例如:
在同一个文件夹中,我同时拥有相同代码(下面的代码)运行 的不同副本,并将值打印到一个公共文件中(Data.txt),例如:\
#define N 10000000
int main(){
FILE* fp_Data;
fp_Data=fopen("Data.txt", "a");
srand48(time(NULL));
int i;
double u;
for(i=0; i<N; i++){
u = drand48();
fprintf(fp_Data, "%f\n", u);
}
fclose(fp_Data);
}
会不会出了什么问题(覆盖了 data/missing 数据)?
[编辑]
正如 Damien 所指出的,关于这个问题也有类似的问题()
在那个问题中,它讨论的是同一进程的不同线程,而不是指向同一文件的独立进程*。
在那种情况下,POSIX 标准(这是我应该在任何使用 unix SO 的电脑上考虑的标准吗?)保证线程安全,这意味着我不会冒 overwritten/missing 数据问题的风险。我现在的疑问是:
对于指向同一个 FILE* 的独立进程也是如此吗?
只要文件是在附加模式下打开的,对文件的每个基础写入都会自动附加到相关文件。
只要 FILE 处于行缓冲模式并且没有行长于 FILE 对象的底层缓冲区大小,每行都将通过对底层文件的单个写入调用来写入。
您使用 fopen 的 "a"
模式以追加模式打开文件。 FILE打开后可以立即用setvbuf设置缓冲区大小和缓冲模式
setvbuf(fp_Data, NULL, _IOLBF, 1024);
如果您将 FILE 保留为默认的块缓冲模式,它将在缓冲区填满时写入基础文件,这很可能在一行的中间。如果多个进程以附加模式写入,这将导致文件中的行混乱。
另一种方法是在每次“记录”完成(可能是多行)时显式刷新 FILE。只要您的记录始终小于缓冲区大小,这将导致每条记录自动附加到文件中。
我对 fprintf()
的工作原理有些怀疑。我读到 fprintf()
不能保证对其写入的文件执行原子追加操作。
这在实践中意味着什么?
考虑以下简单情况,例如:
在同一个文件夹中,我同时拥有相同代码(下面的代码)运行 的不同副本,并将值打印到一个公共文件中(Data.txt),例如:\
#define N 10000000
int main(){
FILE* fp_Data;
fp_Data=fopen("Data.txt", "a");
srand48(time(NULL));
int i;
double u;
for(i=0; i<N; i++){
u = drand48();
fprintf(fp_Data, "%f\n", u);
}
fclose(fp_Data);
}
会不会出了什么问题(覆盖了 data/missing 数据)?
[编辑]
正如 Damien 所指出的,关于这个问题也有类似的问题(
在那个问题中,它讨论的是同一进程的不同线程,而不是指向同一文件的独立进程*。
在那种情况下,POSIX 标准(这是我应该在任何使用 unix SO 的电脑上考虑的标准吗?)保证线程安全,这意味着我不会冒 overwritten/missing 数据问题的风险。我现在的疑问是:
对于指向同一个 FILE* 的独立进程也是如此吗?
只要文件是在附加模式下打开的,对文件的每个基础写入都会自动附加到相关文件。
只要 FILE 处于行缓冲模式并且没有行长于 FILE 对象的底层缓冲区大小,每行都将通过对底层文件的单个写入调用来写入。
您使用 fopen 的 "a"
模式以追加模式打开文件。 FILE打开后可以立即用setvbuf设置缓冲区大小和缓冲模式
setvbuf(fp_Data, NULL, _IOLBF, 1024);
如果您将 FILE 保留为默认的块缓冲模式,它将在缓冲区填满时写入基础文件,这很可能在一行的中间。如果多个进程以附加模式写入,这将导致文件中的行混乱。
另一种方法是在每次“记录”完成(可能是多行)时显式刷新 FILE。只要您的记录始终小于缓冲区大小,这将导致每条记录自动附加到文件中。