管道的原子性

從本質(zhì)上說,管道也是一種文件,但他又和一般的文件有所不同,管道可以克服使用文件進行通信的兩個問題

限制管道的大小。實際上,管道是一個固定大小的緩沖區(qū)。在Linux中該換沖區(qū)的大小為一頁,4k

使得他的大小不像文件那樣不加檢驗的增長。使用固定緩沖區(qū)也會帶來問題,比如再寫管道時可能變滿

當這種情況發(fā)生時,隨后對管道的write()調(diào)用被阻塞,等待某些數(shù)據(jù)被讀取,以便騰出足夠的空間供

write()調(diào)用。

讀取工作也可能比寫的進程快。當所有進程的數(shù)據(jù)被讀取完時,一個隨后的read()調(diào)用將默認的被阻塞、

管道變空。這種情況發(fā)生時,一個隨后的read()調(diào)用將被默認的阻塞,等待某些數(shù)據(jù)被寫入,這樣就解決了read()

調(diào)用將被默認的阻塞,等待某些數(shù)據(jù)將被寫入,這解決了read()調(diào)用返回文件結(jié)束的問題。

一個管道的容量是有限的。POSIX規(guī)定,少于 PIPE_BUF 的寫操作必須原子完成:要寫的數(shù)據(jù)應(yīng)被連續(xù)的寫到管道;大于 PIPE_BUF 的寫操作可能是非原子的: 內(nèi)核可能會把此數(shù)據(jù)與其它進程的對此管道的寫操作交替起來。POSIX規(guī)定PIPE_BUF至少為512B(linux中為4096B),具體的語義如下: 其中n為要寫的字節(jié)數(shù)
    n <= PIPE_BUF, O_NONBLOCK無效:原子的寫入n個字節(jié)。如果管道當前的剩余空間不足以立即寫入n個字節(jié),就阻塞直到有足夠的空間。
    n <= PIPE_BUF, O_NONBLOCK有效:寫入具有原子性,如果有足夠的空間寫入n個字節(jié),write立即成功返回。否則一個都不寫入,返回錯誤,并設(shè)置errno為EAGAIN。
    n >  PIPE_BUF, O_NONBLOCK無效:非原子寫??赡軙推渌膶戇M程交替寫。write阻塞直到將n個字節(jié)寫入管道。
    n >  PIPE_BUF, O_NONBLOCK有效:如果管道滿,則write失敗,返回錯誤,并將errno設(shè)置為 EAGIN。如果不滿,則返回寫入的字節(jié)數(shù)為1~n,即部分寫入,寫入時可能有其他進程穿插寫入。

結(jié)論:
1、當要寫入的數(shù)據(jù)量不大于PIPE_BUF時,linux將保證寫入的原子性。
2、當要寫入的數(shù)據(jù)量大于PIPE_BUF時,linux將不再保證寫入的原子性。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容