UNIX緩衝機制

2021-06-18 20:36:06 字數 1690 閱讀 5757

某日一朋友寫了乙個hello world**,出不來結果,**如下:

#include

int

main(int argc, char **argv)

注意到,在**中printf語句列印的字串最後沒有帶換行符,而且最後呼叫了_exit函式,這導致了在終端螢幕上顯示不出來字串"hello world!"。

首先介紹一下unix裡面關於標準io的幾種緩衝機制:

1、全緩衝 。全緩衝指的是系統在填滿標準io緩衝區之後才進行實際的io操作;注意,對於駐留在磁碟上的檔案來說通常是由標準io庫實施全緩衝。

2、行緩衝 。在這種情況下,標準io在輸入和輸出中遇到換行符時執行io操作;注意,當流涉及終端的時候,通常使用的是行緩衝。

3、無緩衝 。無緩衝指的是標準io庫不對字元進行緩衝儲存;注意,標準出錯流stderr通常是無緩衝的。

其次介紹一下幾個退出函式:

1、exit ()。呼叫exit函式之後,它首先會執行一系列的清理處理,包括呼叫執行各終止處理程式,關閉所有標準io流等,然後進入核心。

2、_exit ()。與exit不同的是,它不進行清理工作而直接進入核心。此函式由posix.1說明,放在unistd.h裡面。

3、_exit ()。同樣,它也不進行清理工作而直接進入核心。此函式跟exit一樣由iso c說明,放在stdlib.h裡面。

現在回過頭來看上面的那段**,很容易發現,由於printf函式是行緩衝的(因為它要往終端輸出資料),而且要列印的字串不帶換行符,因此在它沒有遇到換行符或者沒有填滿緩衝區之前不會進行實際的io操作,而緊接下來的_exit函式又立即進入核心沒有處理io緩衝區,所以我們在終端上看不到hello world語句。

我們可以有很多方法修正這段**。最簡單的莫過於增加乙個換行符:

#include

int

main(int argc, char **argv)

此時行緩衝遇到換行符/n,執行實際io操作。

其次,我們可以呼叫exit函式,讓它幫我們進行相應的io處理:

#include

int

main(int argc, char **argv)

exit函式在進入核心之前,對儲存在緩衝區內的資料進行沖洗,然後關閉io流。

或者,我們可以改變標準輸出流的預設緩衝模式:

#include

int

main(int argc, char **argv)

此時,由於呼叫了setvbuf函式,把標準輸出流預設的行緩衝變成了無緩衝(具體請查閱setvbuf函式實現機制),因此呼叫printf時立即輸出。

當然,我們還可以呼叫fclose函式來達到此目的:

#include

int

main(int argc, char **argv)

實際上,

fclose函式隱含包含了一次fflush操作,把緩衝區內的資料沖洗到終端。

UNIX緩衝機制

某日一朋友寫了乙個hello world 出不來結果,如下 include int main int argc,char argv 注意到,在 中printf語句列印的字串最後沒有帶換行符,而且最後呼叫了 exit函式,這導致了在終端螢幕上顯示不出來字串 hello world 首先介紹一下unix...

UNIX裡面關於標準IO的幾種緩衝機制

編寫背後 國嵌的那段時間,老范曾讓我們幫回答下論壇某個會員的問題,問題 出不來結果,沒任何列印資訊 如下 i nclude main 注意到,在 中printf語句列印的字串最後沒有帶換行符,而且最後呼叫了 exit函式,這導致了在終端螢幕上顯示不出來列印資訊。首先介紹一下unix裡面關於標準io的...

訊息緩衝機制

訊息緩衝是unix系統程序之間進行大量資料交換的機制之一。訊息緩衝是基於訊息佇列的。傳送程序將訊息掛入接收程序的訊息佇列,接收程序從訊息佇列中接收訊息。訊息是指具有型別和數量的乙個資料。訊息分共有和私有的,如果訊息為私有的,只能被建立訊息佇列的程序和其子程序訪問 如果是公有的,可以被系統中知道訊息佇...