C++ 如何确保数据在写入后在磁盘上?
我有一个程序,其中一个线程写入文件,另一个线程读取(同步)。但从某个时候起,写入值和读取值并不相等。实际上,读卡器读取的元素数量正确,但值不同。这可能是不将数据推送到磁盘的问题吗?虽然我在写完后调用了fflush,但如何确保它是编写的,这样我就可以拒绝这个版本。 操作系统-windowsC++ 如何确保数据在写入后在磁盘上?,c++,file,synchronization,fwrite,C++,File,Synchronization,Fwrite,我有一个程序,其中一个线程写入文件,另一个线程读取(同步)。但从某个时候起,写入值和读取值并不相等。实际上,读卡器读取的元素数量正确,但值不同。这可能是不将数据推送到磁盘的问题吗?虽然我在写完后调用了fflush,但如何确保它是编写的,这样我就可以拒绝这个版本。 操作系统-windows FixedSizeQueue::FixedSizeQueue(const std::string& filename, size_t size) : size_(size) , head
FixedSizeQueue::FixedSizeQueue(const std::string& filename, size_t size)
: size_(size)
, head_(0)
, tail_(0)
{
fopen_s(&file_, filename.c_str(), "w+");
InitializeCriticalSection(&critical_section_);
}
void
FixedSizeQueue::push_values(int* values, size_t count)
{
Logger::report("Called push_values");
EnterCriticalSection(&critical_section_);
size_t free_items = (tail_ > head_) ? size_ - tail_ + head_ : size_ - head_ + tail_;
if (count > free_items)
{
Logger::report("Buffer is full, can't push new values.");
exit(1);
}
size_t till_end = (tail_ >= head_) ? size_ - tail_ : head_ - tail_;
if (count < till_end)
{
fseek(file_, tail_ * sizeof(int), SEEK_SET);
int g = fwrite(values, sizeof(int), count, file_);
assert(g == count);
tail_ += count;
}
else
{
fseek(file_, tail_ * sizeof(int), SEEK_SET);
int h = fwrite(values, sizeof(int), till_end, file_);
assert(h == till_end);
fseek(file_, tail_ * sizeof(int), SEEK_SET);
h = fwrite(values + count, sizeof(int), count - till_end, file_);
assert(h == count - till_end);
tail_ = count - till_end;
}
fflush(file_);
LeaveCriticalSection(&critical_section_);
}
size_t
FixedSizeQueue::get_values(int* values)
{
Logger::report("Called get_values");
EnterCriticalSection(&critical_section_);
const size_t item_count = (tail_ >= head_) ? tail_ - head_ : size_ - head_ + tail_;
if (tail_ > head_)
{
fseek(file_, head_ * sizeof(int), SEEK_SET);
fread(values, sizeof(int), item_count, file_);
}
else
{
fseek(file_, (size_ - head_) * sizeof(int), SEEK_SET);
fread(values, sizeof(int), size_ - head_, file_);
fseek(file_, 0, SEEK_SET);
fread(values + size_ - head_, sizeof(int), tail_, file_);
}
head_ = tail_ = 0;
LeaveCriticalSection(&critical_section_);
return item_count;
}
FixedSizeQueue::FixedSizeQueue(const std::string&filename,size\u t size)
:尺寸(尺寸)
,总目(0)
,尾(0)
{
fopen_s(&file_,filename.c_str(),“w+”);
初始化关键部分(&关键部分);
}
无效的
FixedSizeQueue::推送值(int*值、大小\u t计数)
{
记录器::报告(“称为push_值”);
EnterCriticalSection(&critical_section_);
大小\u t自由\u项目=(尾部>头部)?大小\u-尾部+头部:大小\u-头部+尾部;
如果(计数>自由项目)
{
记录器::报告(“缓冲区已满,无法推送新值。”);
出口(1);
}
尺寸直到末端=(尾部>=头部)?尺寸-尾部:头部-尾部;
如果(计数<直到结束)
{
fseek(文件、尾部、大小(int)、搜索集);
int g=fwrite(值、sizeof(int)、计数、文件_u2;);
断言(g==计数);
尾数u+=计数;
}
其他的
{
fseek(文件、尾部、大小(int)、搜索集);
int h=fwrite(值,sizeof(int),直到文件结束);
断言(h==直到最后);
fseek(文件、尾部、大小(int)、搜索集);
h=fwrite(值+计数,sizeof(int),计数-直到结束,文件);
断言(h==count-till_end);
尾=计数-直到结束;
}
fflush(文件);
离开关键部分(和关键部分);
}
尺寸
FixedSizeQueue::获取_值(int*值)
{
记录器::报告(“称为get_值”);
EnterCriticalSection(&critical_section_);
const size\u t item\u count=(tail\u>=head\u)?tail\u-head\u:size\u-head\u+tail;
如果(尾部>头部)
{
fseek(文件、头、大小、搜索集);
fread(值、sizeof(int)、项目计数、文件计数);
}
其他的
{
fseek(文件(大小头)*sizeof(int),SEEK\u集);
fread(值,sizeof(int),size_u-head_u,file_u);
fseek(文件,0,搜索集);
fread(值+大小\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头\头;
}
头=尾=0;
离开关键部分(和关键部分);
退货项目数量;
}
谢谢。这篇存档的知识库文章帮助我们做到了这一点: 最初使用fopen_s打开文件时,我们将“c”模式选项作为最后一个选项:
fopen_s( path, "wc") // w - write mode, c - allow immediate commit to disk
看
然后,由于是Windows,当您想要强制刷新磁盘时,请调用
_flushall()
我们在打电话之前打了这个电话
fclose()
我们遇到了您描述的问题,这种方法解决了它
从上面那篇文章:
Microsoft C/C++7.0版为fopen()引入了“C”模式选项
当应用程序打开一个文件并指定“c”模式时
运行时库在
应用程序调用fflush()或_flushall()函数。“操作系统?读取和写入是否在同一个文件句柄上?Fopen模式?Windows。是的,它是在两个线程中调用的同一个函数,因此具有相同的文件句柄。
是的,它是在两个线程中调用的同一个函数,因此具有相同的文件句柄。
这没有意义。我的意思是,如果在两个线程中使用相同的文件*
变量。你将传递什么给fopen?我使用fopen_s和w+,因为visual给出了一个警告。两个线程做其他工作人员,有时只调用该函数。我并不是在尝试平行读写。