【发布时间】:2012-12-22 01:07:34
【问题描述】:
我正在尝试在写入文件时模拟竞争条件。这就是我正在做的。
- 在 process1 中以追加模式打开 a.txt
- 在 process1 中编写“hello world”
- 在 process1 中打印 ftell,即 11
- 让 process1 进入睡眠状态
- 在process2中以追加模式再次打开a.txt
- 在进程 2 中写入“hello world”(正确附加到文件末尾)
- 在 process2 中打印 ftell 为 22(正确)
- 在进程 2 中写入“再见世界”(正确附加到文件末尾)。
- process2 退出
- process1 恢复并打印其 ftell 值,即 11。
- process1 写“再见世界” --- 我假设 process1 的 ftell 是 11,这应该覆盖文件。
但是,process1 的写操作是写到文件末尾,进程之间没有写争用。
我使用 fopen 作为fopen("./a.txt", "a+)
谁能告诉我为什么会出现这种行为以及如何在写入文件时模拟竞争条件?
process1的代码:
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include "time.h"
using namespace std;
int main()
{
FILE *f1= fopen("./a.txt","a+");
cout<<"opened file1"<<endl;
string data ("hello world");
fwrite(data.c_str(), sizeof(char), data.size(), f1);
fflush(f1);
cout<<"file1 tell "<<ftell(f1)<<endl;
cout<<"wrote file1"<<endl;
sleep(3);
string data1 ("bye world");;
cout<<"wrote file1 end"<<endl;
cout<<"file1 2nd tell "<<ftell(f1)<<endl;
fwrite(data1.c_str(), sizeof(char), data1.size(), f1);
cout<<"file1 2nd tell "<<ftell(f1)<<endl;
fflush(f1);
return 0;
}
在process2中,我已经注释掉了sleep语句。
我正在使用以下脚本运行:
./process1 &
sleep 2
./process2 &
感谢您的宝贵时间。
【问题讨论】:
-
这不是竞争条件。他们按顺序写。
-
我假设当 process1 唤醒时 ftell 为 11,process1 的文件指针 f1 将尝试从那里写入。如何模拟竞争条件,一个进程覆盖另一个进程的内容?谢谢。
-
ftell 可能指向读取缓冲区中的某个位置,但是当涉及到实际文件时 - 您已被序列化。
-
fwrite 如何知道从哪里开始写入数据?它不是存储在进程的文件指针中吗?如果是,则 process1 的 end_of_file 已过时(即 process2 已超出该点写入)。因此,当 process1 恢复写入时,我希望它会使用它的值并立即开始写入。 fwrite 会在写入之前重新计算 EOF 吗?
-
操作系统会处理这个问题。
ftell给你的结果可能是一个库函数错误(如果你愿意,你可以研究它),但是当你以追加方式打开文件时,它会追加。