Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何确保数据在写入后在磁盘上?_C++_File_Synchronization_Fwrite - Fatal编程技术网

C++ 如何确保数据在写入后在磁盘上?

C++ 如何确保数据在写入后在磁盘上?,c++,file,synchronization,fwrite,C++,File,Synchronization,Fwrite,我有一个程序,其中一个线程写入文件,另一个线程读取(同步)。但从某个时候起,写入值和读取值并不相等。实际上,读卡器读取的元素数量正确,但值不同。这可能是不将数据推送到磁盘的问题吗?虽然我在写完后调用了fflush,但如何确保它是编写的,这样我就可以拒绝这个版本。 操作系统-windows FixedSizeQueue::FixedSizeQueue(const std::string& filename, size_t size) : size_(size) , head

我有一个程序,其中一个线程写入文件,另一个线程读取(同步)。但从某个时候起,写入值和读取值并不相等。实际上,读卡器读取的元素数量正确,但值不同。这可能是不将数据推送到磁盘的问题吗?虽然我在写完后调用了fflush,但如何确保它是编写的,这样我就可以拒绝这个版本。 操作系统-windows

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给出了一个警告。两个线程做其他工作人员,有时只调用该函数。我并不是在尝试平行读写。