2011-10-05 84 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