2011-10-05 86 views
2

我正在研究运行linux的智能相机。我从相机流媒体软件捕捉图像并将图像写入SD卡(随相机附带)。为了编写单独的JPEG图像,我使用了fopen和fwrite C函数。为了同步磁盘写操作,我使用fflulsh(指针)清空缓冲区并将数据写入SD卡。但它看起来没有效果,因为写入操作使用系统存储器,每次写入操作后存储器都会减少。我还将低级别的打开和写入功能与fsync(filedesc)结合使用,但它也没有效果。C中的同步写入操作

缓冲区的冲洗发生,只有当我卸载SD卡,然后释放内存。如何禁用此缓存写入而不是SD卡写入?或者如何强制数据同时写入SD卡而不是使用系统内存?

+0

'FSYNC(2)'应该做你想要什么,除非有SD卡驱动程序中的错误,或者你有上启用了写入缓存。 –

回答

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

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

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

欲了解更多详情,请参阅此非常类似的帖子:How can you flush a write using a file descriptor?

1

退房(2)与特定的文件时,FSYNC。

+0

他说他已经试过fsync,但没有奏效。 – RushPL

1

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

当安装磁盘,您可能要指定sync选项(或是使用-o标志mount或在您fstab线。这将确保至少你的写操作都同步写入,这是你应该总是使用对于可移动媒体

1

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

注意fflush()不能保证数据被写入到存储 - 如果你正在使用标准输入输出,你必须首先使用fflush(f),然后fsync(fileno(f))

如果您知道,你不会需要在可预见的将来再次读取数据(很可能为这种情况),您可以关闭该文件之前使用posix_fadvise()POSIX_FADV_DONTNEED标志。

+0

我使用fflush()尝试了高级fopen和fwrite函数,并使用fsync()尝试了低级别的打开和写入函数。在这两种情况下,写入操作都与SD卡同步,但高速缓存始终包含写入数据的副本,因此每次写入操作后可用系统内存都会减少。我还发现,如果SD卡安装了-o sync选项,即使没有fflush()或fsync()也可以使用。然后,我尝试使用echo 1>/proc/sys/vm/drop_caches在每次写入操作后清除缓存。这将在每次写入操作后清除缓存。 – user846400

+0

但令人惊讶的是,图像写入速度非常慢(即,约1图像/秒)。即使我没有清除缓存,让系统内存减少,使用-o sync选项安装SD卡(或使用fflush/fsync),图像保存速度保持不变(即1张图像/秒)。图像以10 FPS(5MP JPEG)的速率捕获。我测量了保存功能的时间,并且保存操作只需60-70毫秒。但我不知道完成写操作需要花费多长时间。 – user846400

+0

@ user846400:为什么你关心的干净页面缓存页面使用的内存目前还不清楚 - 这样的内存来使用,如果需要的(即使你做护理,你可以用'posix_fadvise()'来丢弃这些页面而不是'drop_caches'的大棒)。你的记忆卡可能没有那么快。 – caf