Show Table of Contents
A.3. Fsync
通常
Fsync
是 I/O 密集的運作,但這並不完全正確。
Firefox 會在使用者按下網頁連結,以連上新的頁面時,呼叫 sqlite 函式庫。Sqlite 會呼叫
fsync
,同時因為檔案系統的設定(主要是 ext3 與資料的排序模式),在什麼都沒發生時,會產生很長的延遲時間。如果同時間有另一個程序正在複製大檔案時,這延遲時間會多達 30 秒。
然而在其它不使用
fsync
的情形下,轉換到 ext4 檔案系統上問題就會接踵而來。Ext3 的設定是資料順序模式,每幾秒鐘就會清空記憶體,寫入磁碟去。但在 ext4 與 laptop_mode(筆電模式)下,儲存的間隔較長,系統無預期關機時,資料就會流失。雖然現在 ext4 已經更新,但撰寫應用程式時,還是要注意,並適當地使用 fsync
。
以下這個簡單的範例會讀、寫一個配置檔,顯示了如何備份檔案,以及資料是怎麼流失的:
/* open and read configuration file e.g. ./myconfig */ fd = open("./myconfig", O_RDONLY); read(fd, myconfig_buf, sizeof(myconfig_buf)); close(fd); ... fd = open("./myconfig", O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); write(fd, myconfig_buf, sizeof(myconfig_buf)); close(fd);
較好的方法是:
/* open and read configuration file e.g. ./myconfig */ fd = open("./myconfig", O_RDONLY); read(fd, myconfig_buf, sizeof(myconfig_buf)); close(fd); ... fd = open("./myconfig.suffix", O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR write(fd, myconfig_buf, sizeof(myconfig_buf)); fsync(fd); /* paranoia - optional */ ... close(fd); rename("./myconfig", "./myconfig~"); /* paranoia - optional */ rename("./myconfig.suffix", "./myconfig");