C中的同步写操作

时间:2011-10-05 15:53:22

标签: c++ c

我正在开发一款运行linux的智能相机。我从相机流媒体软件中捕获图像,并将图像写入SD卡(附带相机)。为了编写单独的JPEG图像,我使用了fopen和fwrite C函数。为了同步磁盘写操作,我使用fflulsh(指针)刷新缓冲区并在SD卡上写入数据。但它似乎没有效果,因为写操作使用系统内存,并且每次写操作后内存都会减少。我还使用低级开放和写入函数与fsync(filedesc)一起使用,但它也没有任何效果。

只有当我卸下SD卡然后释放内存时才会刷新缓冲区。如何禁用此缓存写入而不是SD卡写入?或者如何强制数据同时写入SD卡而不是使用系统内存?

5 个答案:

答案 0 :(得分:3)

sync(2)可能是您最好的选择:

SYNC(2)                    Linux Programmer's Manual                   SYNC(2)

NAME
       sync - commit buffer cache to disk

SYNOPSIS
       #include <unistd.h>

       void sync(void);

DESCRIPTION
       sync() first commits inodes to buffers, and then buffers to disk.

BUGS
       According  to  the  standard specification (e.g., POSIX.1-2001), sync()
       schedules the writes, but may return before the actual writing is done.
       However,  since  version  1.3.20 Linux does actually wait.  (This still
       does not guarantee data integrity: modern disks have large caches.)

答案 1 :(得分:1)

如果您使用O_SYNC打开文件,则可以设置open(),或者按照上面的建议使用sync()

使用fopen(),您可以使用fsync(),或使用fileno()ioctl()的组合来设置描述符的选项。

有关详细信息,请参阅此类非常相似的帖子:How can you flush a write using a file descriptor?

答案 2 :(得分:1)

使用特定文件时,请查看fsync(2)。

答案 3 :(得分:1)

你可能真的没有什么可以做的。许多文件系统都大量缓存在内存中,因此写入文件可能无法立即写入磁盘。在这种情况下保证写入的唯一方法是实际卸载驱动器。

安装磁盘时,您可能需要指定sync选项(使用-omount行中的fstab标记。这将确保至少你的写入是同步写的。这是你应该总是用于可移动媒体的。

答案 4 :(得分:1)

仅仅因为它仍占用内存并不意味着它还没有被写入存储 - 干净(与物理存储上的副本相同)数据副本将保留在页面缓存,直到其他内容需要该内存,以防应用程序稍后再读取该数据。

请注意,fflush()无法确保数据已写入存储空间 - 如果您使用的是stdio,则必须先使用fflush(f),然后使用fsync(fileno(f))

如果你知道在可预见的未来你不需要再次阅读这些数据(这种情况似乎很可能),你可以posix_fadvise()使用POSIX_FADV_DONTNEED关闭文件之前的标志。