認真理一理這些奇怪緩衝問題

2021-10-04 18:50:34 字數 3285 閱讀 3574

與緩衝相關的函式

我們知道標準錯誤永遠是無緩衝的。當標準輸入輸出指向的是互動式裝置(如終端)的時候,它們是行緩衝的。若不是則是全緩衝的。

那麼這些預設的緩衝型別如何修改?其實可以通過這些函式修改:

#include

void

setbuf

(file *stream,

char

*buf)

;void

setbuffer

(file *stream,

char

*buf, size_t size)

;void

setlinebuf

(file *stream)

;int

setvbuf

(file *stream,

char

*buf,

int mode, size_t size)

;

引數說明如下:

stream file *型別,檔案指標

buf 緩衝區指標

mode 緩衝模式,包括_iofbf(全緩衝),_iolbf(行緩衝),_ionbf(不帶緩衝)

size 緩衝區大小

setbuf()的緩衝區長度必須為bufsiz(定義在stdio.h),否則可能會出現緩衝區溢位。setbuffer可以指定緩衝區大小。

void setbuf ( file * stream,

char

* buffer )

;//同setbuf,但可指定緩衝區大小

void

setbuffer

(file *stream,

char

*buf, size_t size)

;

使用setbuf函式開啟或者關閉緩衝,當buf是乙個有效緩衝區時,此時緩衝開啟,若流指向的是終端裝置,則此時該流是行緩衝的,否則該流是全緩衝的;當buf為null的時候,表示關閉該緩衝。

將buffer指定為null,關閉標準輸出緩衝。

#include

#include

intmain

(int argc,

char

const

*ar**)

編譯執行

通過設定stdout(標準輸出)的第二個引數為null,將其變成了不帶緩衝,因此你執行後發現,printf的列印會立即顯示在終端。

使用setvbuf可以精確的說明緩衝的型別,這裡是使用mode來說明的,mode的值包括以下幾個

_iofbf 全緩衝

_iolbuf 行緩衝

_ionbuf 無緩衝

如果指定乙個不帶緩衝的流,則忽略buf和size引數。如果指定緩衝,則buf和size分別指定乙個緩衝區域和緩衝區域的長度。若此時buf為null,則標準io庫將自動制定乙個適合長度的緩衝區。

#include

#include

intmain

(int argc,

char

const

*ar**)

編譯執行

設定為不帶緩衝

標準i/o庫不進行任何字元緩衝,任何讀寫都是即時可見的。linux下標準錯誤輸出預設是不緩衝,來看乙個例子:

#include

#include

intmain

(int argc,

char

const

*ar**)

編譯執行

編譯執行上面的程式,結果就比較顯而易見了。程式一執行的時候就會輸出」hello「,過兩秒輸出」程式猿編碼「,再過兩秒程式就結束了。

在c語言中,可以通過setbuf來設定無緩衝模式,只要將第二個引數設定為null就可以了;

也可以通過setvbuf來設定無緩衝模式,其中_ionbf表示行緩衝,就是io not buffer的意思。

printf列印的日誌沒有輸出

不知道你有沒有遇到過這樣的情況,準備除錯某乙個bug,發現每次執行到某個地方,列印就結束了,然後就掛了,讓你誤以為程式執行到列印的地方就結束了。

然而有可能程式執行到後面,只是由於列印是行緩衝的,導致部分列印沒有出來,很可能就是你沒有加上換行符列印而已。

這時候你可以設定為不帶緩衝,或者關鍵位置fflush,或者列印記得加上換行符。

當然你還可以用gdb《gdb除錯入門,看這篇就夠了!》

控制檔案i/o的核心緩衝

在某些情況下,我們可能需要強制將核心緩衝區內的資料重新整理至磁碟,而不必等待核心執行緒等待特定時間後才寫入。此時主要有兩種選擇

1、使用fsync,fdatasync, sync系統呼叫中的某乙個將核心緩衝區的資料強制寫入磁碟

2、以o_sync同步方式呼叫open開啟檔案,此後每次讀寫操作都會自動立即寫入磁碟

#include

intfsync

(int fd)

;int

fdatasync

(int fd)

;void

sync

(void

);

fsync保證同步i/o檔案完整性,fdatasync保證同步i/o資料完整性。

兩個完整性的區別在於前者會將所有更新的檔案元資料寫入磁碟,後者不會傳遞所有經過修改的檔案元資料屬性(如:時間戳)。

fsync與fdatasync均是重新整理指定檔案流資料,而sync()函式會更新所有核心緩衝區資料至磁碟,對應shell指令sync。

參考:《linux/unix系統程式設計手冊》

要命的定義函式。。。引數組合。請認真理解!

def test args kwargs arg1,arg2,arg3 print arg1 arg1 print arg2 arg2 print arg3 arg3 使用 args 和 kwargs 來呼叫函式 首先使用 args args two 3,5 test args kwargs arg...

認真是一種能力

前一陣看乙個教育電視節目,說的是小學生經常粗心,於是乙個老師出來講,認真是一種能力,這種能力需要經過鍛鍊,讓學生真正體會到什麼是認真,他才會不再粗心。看了之後,忽然大悟。以前在作績效考核時,一般是分三個方面打分,能力 業績 態度。這認真 主動等等主觀感覺,一般放在態度裡面。以前有時覺得兩人能力其實還...

認真是一種能力

正規表示式的書稿終於結束了 暫定名 正則導引 關上電腦細細思考,寫完這三十萬字,最深刻的感受是什麼?我的回答是 後悔。從2009年初我打算寫這本書,到2011年年中正式寫完,一共花費了兩年多時間,期間雖然經歷了許多變故,有些事情也無可避免,但其實不用花費這麼長時間 最初是在周筠老師的鼓勵下決定動筆,...