LINUX系統程式設計 關於SDTIO庫緩衝區
我們知道標準C中的檔案讀取的函式比如printf,fwrite等函式,實際都是呼叫OS級別的
API,比如LINUX下就是wirte,read函式,而write read函式在使用者態下是沒有緩衝的,
當然在核心態有OS CACHE/OS BUFFER,所以某些直接呼叫wirte,read的程式肯定會
分配一個緩衝區,特別是O_DIRECT這種方式下,核心態的OS CACHE和OS BUFFER沒用
這種情況下使用者態的BUFFER顯得更加重要,因為不可能一次讀一個位元組吧,那效能可想而知
而作為使用者態空間的STDIO也是這樣做的,它會為開啟的檔案分配快取,預設應該是8192位元組
如下圖摘自UNIX系統程式設計手冊 13章:
實際上我們可以使用setvbuf來設定某個開啟檔案的緩衝大小及模式。
我們來看看原型:
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
返回0為成功,非零為失敗
FILE *stream:開啟檔案的FILE*
char *buf:BUFFER的地址,如果為NULL,MODE為_IOLBF和_IOFBF則自動分配緩衝區
如果為_IONBF則不分配緩衝區
int mode:_IONBF不使用緩衝區,立即呼叫write/read,忽略buf和size為NULL和0,stderr屬於這個
_IOLBF使用行緩衝I/O,終端裝置預設為這種。要麼遇到換行符要麼緩衝滿才呼叫write/read,
stdin/stdout屬於這個。
_IOFBF採用全緩衝I/O,buffer滿才呼叫write/read,磁碟I/O屬於這個比如fwrite/fread
size_t size:緩衝大小
更簡單函式setbuf原型如下:
void setbuf(FILE *stream, char *buf);
相當於
setvbuf(fp,buf,(buf !=NULL)?_IOFBF:_IONBF,BUFSIZ);
如果buf=NULL則_IONBF開啟不帶緩衝,或者呼叫全緩衝,BUFSIZ預設8192。
所以我們如果不想用緩衝直接:
setvbuf(fp,NULL)
即可。
現在回想一下fread
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
fread的時候我們通常要calloc一塊記憶體用於void *ptr,那麼現在我們想一下實際
上這個資料正常快取到了3個地方
1、使用者分配的記憶體*ptr
2、STDIO的快取預設8192
3、核心態OS CACHE
這視乎有點臃腫,我們可以想辦法簡化。事實上資料庫軟體有時候只使用了使用者態
的一份快取,而開啟O_DIRECT來提高效能。
下面一個小程式可以驗證開啟和關閉stdout緩衝的區別:
int main(void)
{
int i;
// setbuf(stdout,NULL);
for(i=0;i<10;i++)
{
printf("-");
sleep(1);
}
printf("\n");
}
區別就是是否使用setbuf,如果使用setbuf則 -符號會一個一個輸出,不使用會一起輸出
這就是STDIO快取在作怪。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2129558/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Socket程式設計注意接收緩衝區大小程式設計
- C 標準庫IO緩衝區和核心緩衝區的區別
- Linux 命令 管道 緩衝區Linux
- 關於資料庫緩衝池的問題資料庫
- 【Linux】關於Linux的系統程式設計總結Linux程式設計
- Golang併發程式設計有緩衝通道和無緩衝通道(channel)Golang程式設計
- Python網路程式設計(socket模組、緩衝區、http協議)Python程式設計HTTP協議
- 緩衝區分析
- 緩衝區溢位小程式分析
- LINUX系統程式設計 LINUX地區(locale)設定Linux程式設計
- Linux系統共享庫程式設計(轉)Linux程式設計
- ASLR 是如何保護 Linux 系統免受緩衝區溢位攻擊的Linux
- Java NIO:緩衝區Java
- getchar緩衝區
- 調節Oracle資料緩衝區引數,緩衝整個資料庫(轉)Oracle資料庫
- 關於系統分析設計
- Oracle資料庫緩衝區命中率(轉)Oracle資料庫
- Java NIO 之緩衝區Java
- Unity深度緩衝區指令Unity
- Java整數緩衝區Java
- nginx 緩衝區構造Nginx
- 網際網路和區域網網路程式設計Socket緩衝區最優總結程式設計
- LINUX系統程式設計 SWAP原理以及和資料庫(MYSQL ORACLE)關係Linux程式設計資料庫MySqlOracle
- Node.js Buffer(緩衝區)Node.js
- PHP的輸出緩衝區PHP
- JavaScript WebGL 幀緩衝區物件JavaScriptWeb物件
- log buffer(日誌緩衝區)
- Java NIO 之 Buffer(緩衝區)Java
- Java NIO2:緩衝區Java
- 動態更新——緩衝區物件物件
- 架構設計:生產者/消費者模式[4]:雙緩衝區架構模式
- 【Linux系統程式設計】libevent庫bufferevent與evconnlistenerLinux程式設計
- PHP 輸出緩衝區應用PHP
- Java-NIO之Buffer(緩衝區)Java
- Redis效能篇(五)Redis緩衝區Redis
- 8、Node.js Buffer(緩衝區)Node.js
- node.js中緩衝區–BufferNode.js
- C語言緩衝區問題C語言