关于write()和fsync()
--關(guān)于write()和fsync() ?
----------------------------轉(zhuǎn)載
?
write
ssize_t write(int fd, const void *buf, size_t count);
將數(shù)據(jù)寫到文件中. 注意, 如果文件是保存在硬盤中, write() 函數(shù)調(diào)用返回之后, 并不表示數(shù)據(jù)已經(jīng)寫入到硬盤中, 這時如果掉電, 數(shù)據(jù)可能會丟失.
fsync
int fsync(int fd);
程序調(diào)用本函數(shù), 通知內(nèi)核把數(shù)據(jù)寫到硬盤(file)中. 比如, 你開發(fā)一個數(shù)據(jù)庫軟件, 就需要這樣的函數(shù), 否則掉電或者系統(tǒng)崩潰時便會丟失數(shù)據(jù).
如果你的程序不調(diào)用 fsync(), Linux 內(nèi)核也會自動在”合適”的時候?qū)⒛愕臄?shù)據(jù)真正寫入到硬盤(類似調(diào)用 fsync), 最長的延時默認是 30 秒.
阻塞?
阻塞是 IO 的精華所在, 不管是文件 IO 還是網(wǎng)絡(luò) IO, 只有真正了理解了 IO 阻塞, 才能做出所謂在高并發(fā)高性能軟件(服務(wù)器).
當(dāng) fsync() 和 write() 同一個 fd 時, write() 必然阻塞. 當(dāng)系統(tǒng) IO 非常繁忙時, fsync() 可能會阻塞, 即使系統(tǒng) IO 不繁忙, fsync() 也會因為數(shù)據(jù)量大而慢.
注:?許多 Linux 系統(tǒng)函數(shù)如 read(), write() 等, 粗看起來很簡單, 也很容易用. 正如所有的事情一樣, 要做到精致肯定不簡單. 當(dāng)你脫離初級的學(xué)習(xí)階段, 要寫真正生產(chǎn)環(huán)境的軟件時, 這些”簡單”的函數(shù)就大有門道了. 你需要不斷的閱讀它們的手冊, 了解每一個參數(shù), 每一個返回值, 同時還要閱讀和試驗在各種條件和環(huán)境下這些函數(shù)的表現(xiàn), 這樣, 才有可能做出真正的軟件.
?
?
關(guān)于write()和fsync()
樓主password636(亮)2006-03-02 18:08:38 在 Linux/Unix社區(qū) / 程序開發(fā)區(qū) 提問
關(guān)于linux系統(tǒng)調(diào)用write() ??
? 調(diào)用一次write()完畢,是不是已經(jīng)寫到磁盤上了? ??
? 是不是調(diào)用一次write(),就是一次寫請求,不管寫多少個字符進去,調(diào)用完都已經(jīng)通過緩沖區(qū)寫到磁盤上了? ??
? 那么fsync()這個函數(shù)是不是指將緩沖區(qū)的寫到磁盤上,如果是,write完再fsync是不是多此一舉? ??
? 我想實現(xiàn)的是可以先創(chuàng)建一個文件,然后寫一些東西到該文件的緩沖區(qū),再調(diào)用fsync()寫入磁盤,請問如何實現(xiàn)? ??
??問題點數(shù):10、回復(fù)次數(shù):7Top
?
1 樓morpheus1977()回復(fù)于 2006-03-03 22:07:46 得分 0
write() ? 是不帶緩存的。 ? 應(yīng)該不用吧。Top
2 樓tb01412(tb)回復(fù)于 2006-03-03 22:49:08 得分 0
所謂write不帶緩存是指不在C庫中緩存,只要應(yīng)用層調(diào)用write,就直接發(fā)出write系統(tǒng)調(diào)用,而內(nèi)核中的write塊設(shè)備都是有緩存的,所以就需要fsync將磁盤高速緩沖中的數(shù)據(jù)立刻寫入磁盤中去!!!!!Top
3 樓password636(亮)回復(fù)于 2006-03-04 12:32:50 得分 0
但是為什么我write()完后,用stat()輸出st_size,就是寫入的個數(shù)呢?要是有緩存,應(yīng)該是0啊?Top
4 樓tb01412(tb)回復(fù)于 2006-03-04 13:11:31 得分?10
呵呵,當(dāng)你用write之后,內(nèi)核就響應(yīng)write系統(tǒng)調(diào)用,然后向高速磁盤緩沖塊寫入數(shù)據(jù),之后,你如果用stat,或者read時,系統(tǒng)首先會在高速緩沖塊中去查看相應(yīng)的數(shù)據(jù)是否在塊中,如果不是,然后再調(diào)用磁盤驅(qū)動加載磁盤數(shù)據(jù)到高速緩沖塊中,然后再由高速緩沖塊中返回你要的數(shù)據(jù)!!!!!這就是你用stat()輸出st_size,就是寫入的個數(shù)的原因!!!!! ??
? 系統(tǒng)會在合適的時機再向真正的硬件寫入高速緩沖塊中的數(shù)據(jù),也可以用fsync強制把高速緩沖塊中的相應(yīng)數(shù)據(jù)寫入磁盤!!!!!!!Top
5 樓password636(亮)回復(fù)于 2006-03-05 18:31:56 得分 0
如何能證明fsync()是強制從緩存寫到磁盤上的? ??
? 我開始想證明fsync()是這樣打算的,用open()創(chuàng)建一個文件,用write()寫,然后用stat()獲得一個size,之后調(diào)用fsync(),調(diào)用完后再用stat()獲得一次size,開始由于對stat()的不理解,覺得stat()是從磁盤上讀大小,第一次讀應(yīng)該是0,第二次即fsync()后讀應(yīng)該是write()進去的大小,可現(xiàn)在知道了stat()和read()都是從緩存中獲得數(shù)據(jù),那么有沒有其他的辦法在write()后fsync()前獲得文件在磁盤上的大小?如果獲得不了,那有什么辦法能證明fsync()是從緩存強制寫到磁盤上的?Top
6 樓tb01412(tb)回復(fù)于 2006-03-06 13:05:56 得分 0
如果只想證明fsync()是從緩存強制寫到磁盤上的話,很簡單: ??
? 使用U盤,你先向上面寫入大量的數(shù)據(jù)(比如幾十M),接著程序退出,然后馬上拔出U盤(不要用umount),之后再將U盤插入,mount上去,然后再讀出原來的文件內(nèi)容,估計文件最后的內(nèi)容不再是你原來寫入的內(nèi)容了!!!! ??
? ??
? 還有一種辦法: ??
? 不通過磁盤緩沖讀取數(shù)據(jù),比如你想讀sda1上的文件數(shù)據(jù),直接用open("/dev/sda1"),而不再用實際文件目錄的方式來操作,不過這樣你需要自己去解析相應(yīng)文件系統(tǒng)在磁盤上的物理組織格式才行Top
7 樓fgmIsdn()回復(fù)于 2006-03-09 15:37:43 得分 0
緩沖區(qū)有多個層次,OS內(nèi)核肯定有,驅(qū)動程序也可能有,而且現(xiàn)在流行的硬盤驅(qū)動器上也有。 ??
? fsync()一般不要使用,立即寫入硬盤磁介質(zhì)上,會產(chǎn)生很多次寫入動作,有損硬盤壽命,硬盤的性能也會收到影響。 ??
? ??
? 硬盤涉及到比較復(fù)雜的技術(shù)。 ??
? 目前IDE硬盤從2MB緩存向8MB緩存過渡,大容量有16MB的。
轉(zhuǎn)載于:https://www.cnblogs.com/jackhub/p/3792739.html
總結(jié)
以上是生活随笔為你收集整理的关于write()和fsync()的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: window.onload和$(docu
- 下一篇: 一个功能函数所具备的要素