sync、fsync、fdatasync三個函數以及O_SYNC標誌位的區別

在大多數的unix/linux對磁盤io的寫操作都是通過緩存來完成的,基本的原理如下:當將數據寫入文件時,內核通常先將該數據複製到其中一個緩衝區中,如果該緩衝區尚未寫滿,則並不將其排入輸出隊列,而是等待其寫滿或者當內核需要重用該緩衝區以便存放其他磁盤塊數據時,再將該緩衝排入輸出隊列,然後待其到達隊首時,才進行實際的I/O操作。 我們稱之爲延遲寫,極大的減少了寫磁盤的次數。
但是在沒寫特殊的應用中我們需要實時的將應用層數據寫入到磁盤上 特別是一些高可靠性要求的系統中 數據需要及時的寫入磁盤 即便是瞬時系統故障 數據也可以安全恢復,於是就有了sync、fsync和fdatasync函數。但在功能上 這三個函數又略有區別:

     sync函數只是將所有修改過的塊緩衝區排入寫隊列,然後就返回,它並不等待實際寫磁盤操作結束。通常稱爲update的系統守護進程會週期性地(一般每隔30秒)調用sync函數。這就保證了定期沖洗內核的塊緩衝區。

    fsync函數只對由文件描述符filedes指定的單一文件起作用,並且等待寫磁盤操作結束,然後返回。fsync可用於數據庫這樣的應用程序,這種應用程序需要確保將修改過的塊立即寫到磁盤上。

    fdatasync函數類似於fsync,但它隻影響文件的數據部分。而除數據外,fsync還會同步更新文件的屬性。

     這裏需要特別說明一下的是 目前glibc中fdatasync函數的實現已經和fsync一摸一樣了:

   

/* Synchronize at least the data part of a file with the underlying
   media.  */
int
fdatasync (int fildes)
{
  return fsync (fildes);
}
另外,
我的感覺是描述符設置了O_sync標識後,每次write都會等到真正寫到磁盤後才返回。
而對於fsync類函數,應該是這樣使用
write(fd,string,len); // 先write
fsync(fd);            // 然後強制同步
這裏fsync會等到真正寫到磁盤後才返回,而不是write會等到真正寫到磁盤後才返回。
這裏也有一篇文章,講了一下,英文不好,看不大懂,囧http://blog.csdn.net/cindy9902/article/details/5827183
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章