1. 程式人生 > >標準的I/O緩衝:全緩衝,行緩衝,無緩衝

標準的I/O緩衝:全緩衝,行緩衝,無緩衝

今天在學習程序時遇到關於一個I/O緩衝區的的問題,和大家分享一下,首先舉個簡單的例子:

#include <stdio.h>
int main()                                                                      
{
        printf("hello,world!");
        _Exit(0);
}

編譯成功後卻不出現hello,world,這是為什麼呢,注意,在程式碼中printf語句列印hello,world的字串最後面沒帶換行符.而且最後呼叫了_Exit函式,這導致了在終端上顯不出hello,world. 首先介紹關於標準I/O的幾種緩衝機制: 1.全緩衝

:全緩衝指的是系統在填滿標準的I/O緩衝區後才進行實際的I/O操作,注意,對於駐留在磁碟上的檔案來說通常是由標準的I/O庫實施全緩衝. 2.行緩衝: 在這種情況下,標準的IO在輸入和輸出中遇到換行符執行IO操作;注意,當流涉及終端時,都使用行緩衝. 3.無緩衝:無緩衝指的是標準的IO庫不對字元進行緩衝儲存,注意,標準的出錯流stderr通常是無緩衝的. 在看幾個退出函式: 1.exit(),呼叫exit函式之後,它首先執行一系列的清理處理,包括呼叫執行各種終止處理程式,關閉所有標準IO流等,然後進入核心; 2._exit().與exit不同的是,它不進行清理直接進入核心此函式由POSIX.1說明,放在unistd.h裡面. 3._Exit ()
。同樣,它也不進行清理工作而直接進入核心。此函式跟exit一樣由ISO C說明,放在stdlib.h裡面。 所以可以有很多方法修正這段程式碼: 1.在hello,world後加一個換行符,此時行緩衝遇到換行符\n.執行實際IO操作. 2.呼叫exit()函式,讓它幫我們進行相應的IO操作,也就是把_Exit(),換成exit(); 3.改變標準的輸出流的預設緩衝區,這個要用到函式setvbuf(),那就先介紹以下這個函式吧: #include <stdio.h> 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); 函式說明: 1.對於setbuf()函式,buf指出的緩衝區長度由標頭檔案stdio.h中定義的 巨集BUFSIZE的值決定,預設值為512位元組。當選定buf為空時,setbuf函式將使的檔案I/O不帶緩衝。 2.setvbuf函式,則由 malloc函式來分配緩衝區。引數size指明瞭緩衝區的長度(必須大於0),而引數type則表示了緩衝的型別,其值可以取如下值: 3.在開啟檔案流後,讀取內容之前,呼叫setbuffer()可用來設定檔案流的緩衝區。引數stream為指定的檔案流,引數buf指向自定的緩衝區起始地址,引數size為緩衝區大小。 4. setlinebuf()用來設定檔案流以換行為依據的緩衝IO,即行緩衝。 type 值 含義 _IOFBF 檔案全部緩衝,即緩衝區裝滿後,才能對檔案讀寫 _IOLBF 檔案行緩衝,即緩衝區接收到一個換行符時,才能對檔案讀寫 _IONBF 檔案不緩衝,此時忽略buf,size的值,直接讀寫檔案,不再經過檔案緩衝區緩衝 所以我們可以通過呼叫setvbuf函式,把標準的輸出流預設的行緩衝變成無緩衝 setvbuf(stdout, NULL, _IONBF, 0);
 現在說一說我今天遇到的具體的問題吧,大家都知道,fork一個子程序,子程序會複製父程序的許多資源(這個自己查),最重要的是它會複製父程序的緩衝區, 舉個例子吧,

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
extern char **environ;
int main()
{
        pid_t pid;
        int stat_val;
        char *argv[]={"ls","-al","/",NULL};
        //printf("exec函式族例項:\n");//去掉註釋;
        printf("exec函式例項:");
        pid=fork();
        switch(pid) {
        case -1:
                perror("程序建立失敗!\n");
                exit(1);
        case 0:
                printf("子程序正在執行!\n");
                printf("我的ID=%d,父親的ID=%d\n",getpid(),getppid());   
                //execve("/bin/ls",argv,environ);
                //execv("/bin/ls",argv);
                //execvp("ls",argv);
                //execl("/bin/ls","ls","-al","/",NULL);
//              execlp("ls","ls","-al","/",NULL);
                execvp("ls",argv);
                printf("如果exec函式呼叫成功,這一句不會被執行!\n");
                exit(0);
        default:
                
                printf("父程序正在執行!\n");
                break;                                                                                                                          
        }       
        wait(&stat_val);

        return 0;
}

編譯執行:

[email protected]:~/Linux C$ gcc processimage1.c 
[email protected]:~/Linux C$ ./a.out
exec函式例項:父程序正在執行!
exec函式例項:子程序正在執行!
我的ID=6032,父親的ID=6031
總用量 105
drwxr-xr-x  24 root root  4096  7月 13 12:11 .
drwxr-xr-x  24 root root  4096  7月 13 12:11 ..
drwxr-xr-x   2 root root  4096  5月 31 11:42 bin

然後把註釋寫//去掉註釋那一行註釋去掉,註釋掉下面那一行: 編譯執行:

exec函式族例項:
父程序正在執行!
子程序正在執行!
我的ID=7354,父親的ID=7353
總用量 105
drwxr-xr-x  24 root root  4096  7月 13 12:11 .
drwxr-xr-x  24 root root  4096  7月 13 12:11 ..
drwxr-xr-x   2 root root  4096  5月 31 11:42 bin
drwxr-xr-x   4 root root  1024  5月 31 14:20 boot

第一次沒有加進行加\n,所以父程序執行後"exec函式族例項:"就存在於父程序的緩衝區中,當fork後,子程序也複製了父程序的緩衝區,所以輸出了兩次"exec函式族例項", 第二次,加了\n,進行了行緩衝清理,所以只由父程序輸出一次;

相關推薦

Linux下標準I/O緩衝機制

平臺:Ubuntu作業系統 編譯器:g++ 首先讓我們看一段程式碼: #include <iostream> #include <unistd.h> using namespace std; int main() { for (int i

C++標準I/O庫:iostream, fstream, sstringstream

sso www c const ams 生效 系列 linux 引用 binary 在寫代碼的過程中。我們最常做的事就是io操作,不管是對控制臺,還是文件。但一段時間不寫代碼就忘了,這裏理一下C++標準I/O庫的詳細類和操作。 C++的標準I/O庫包含我們常常使用的io

標準I/O讀寫文件

sizeof linux 文件 文件的 main 方式 次數 col tdi 一、函數原型   1、FILE *fopen(const char *path, const char *mode);     path:要打開文件路徑及文件名;     mode: r 打開只

標準I/O及管道的使用用法

管道 標準i/o 程序:指令+數據 讀入數據 :Input 輸出數據 :Output Linux給程序提供的三種I/O設備 標準輸入,-O 默認接受來自鍵盤的輸入 標準輸出,-1 默認輸出到終端窗口 標準錯誤,-2 默認輸出到終端窗口> 文件內

C 標準I/O庫粗略實現

介紹 功能 問題: 關系 請求 頻繁 determine 不出 tin 本文同時發表在 https://github.com/zhangyachen/zhangyachen.github.io/issues/123 寫一下fopen/getc/putc等C庫的粗略實現,參考

Linux——標準I/O以及管道

run 克服 標準 ech 習慣 進程間 nsf lin sof 標準I/O以及管道目錄一、什麽是I/O二、什麽是管道三、三種I/O設備四、把I/O輸出錯誤重定向入文件五、tr六、從文件中導入STDIN七、使用管道鏈接命令八、tee一、什麽是I/O I/O(input

Unix環境高級編程(三)標準I/O

buffer 文件創建 fop read 通信通道 種類 目的 lose com   標準I/O庫是ISO C的標準,在很多操作系統上面都實現。Unix文件I/O函數都是針對文件描述符的,當打開一個文件的時候,返回該文件描述符用於後續的I/O操作。而對於標準I/O庫,操作

第四章標準I/O和管道

I/O 重定向 管道 筆記整體起始時間:2018年4月2日18:55:25 本章內容 三種I/O設備 把I/O重定向至文件 使用管道 標準輸入和輸出 程序:指令+數據 讀入數據:Input

Linux學習第五節課-標準I/O和管道

定向 描述 命令 終端 NPU 提示 err 輸出數據 所有 Linux學習第五節課------------------------------------

標準I/O和管道

eas 命令 git 文件 .sh user 輸出 一行 源碼安裝 一部分:標準I/O和管道 1:Linux給程序提供三種I/O設備 ?標準輸入(STDIN)-0 默認接受來自鍵盤的輸入 ?標準輸出(STDOUT)-1 默認輸出到終端窗口 ?標準錯誤(STDERR)-2

Linux的標準I/O和管道

導入 結果 鍵盤 nbsp tle pan 圖片 cto 刪除字符 標準輸入輸出與管道 1、標準輸入和輸出 程序:指令+數據 指令:計算、加減乘除 數據:輸

第五章 標準I/O

依靠 成員 終端設備 添加 緩沖區 pan getc orm ron 5.1 引言 本章說明標準 I/O 庫。因為不僅在 UNIX 上,而且在很多操作系統上都實現了此庫,所以它由 ISO C 標準說明。 標準 I/O 庫處理很多細節,例如緩沖區分配,以優化長度執行

25 Java學習之標準I/O流重定向

Java的System類提供了一些簡單的靜態方法呼叫,以允許我們對標準輸入、輸出和錯誤I/O流進行重定向: setIn(InputStream) setOut(PrintStream) setErr(PrintStream) 如果我們突然開始在顯示器上建立大量輸出,而這些輸出滾動得太快以

C++標準I/O

流介紹 標準I/O類的標頭檔案    <iostream>  包含istream、ostream、iostream這三個類。其中,iostream由istream和ostream派生而來。

文件I/O標準I/O函數

size seek putchar 文件指針 安全 二進制 fputs exit 函數 讀取/寫入 相對於文件而言 輸入/輸出 相對於程序/內存而言 一切皆文件,鍵盤、顯示屏也是文件,只不過是特殊的標準文件; 標準文件:標準輸入、標準輸出、標準錯誤;---->對應的

Linux 環境程式設計——淺談標準I/O緩衝區

標準I/O庫提供緩衝的目的是儘可能地減少使用read和write呼叫的次數。它也對每個I/O流自動地進行緩衝管理,從而避免了應用程式需要考慮這一點所帶來的麻煩。不幸的是,標準I/O庫最令人迷惑的也是它的緩衝。   標準I/O提供了三種類型的緩衝: 1、全緩衝: 在填滿標準I

C primier plus 第十三章 13.2標準I/O

首先,關於main(int argc,char *argv[ ])。參考百度百科中的解釋。 https://baike.baidu.com/item/argc%20argv/10826112?fr=aladdin 1. argc的值是命令列引數的個數 什麼是命令列引數? 在命令列下呼

APUE第5章 標準I/O

1、概述 標準I/O庫處理很多細節,如緩衝區分配、以優化的塊長度執行I/O等。這些處理使使用者不必擔心如何選擇使用正確的長度。本章深入瞭解I/O庫函式的操作。 2、流和FILE物件 對於所有I/O函式(見第3章)都圍繞檔案描述符的。當開啟一個檔案時,即返回一個檔案描述符

標準I/O

tel 下一個 相關 chat 寫入 使用 進制 set lose 設置流的定向: #include <stdio.h> #include <wchar.h> // 流的定向決定了所讀、寫的字符是單字節(字節定向)還是多字節的(寬定向) // 若

Linux環境程式設計---標準I/O

前面的章節主要介紹linux的系統呼叫,這一節介紹linux的C庫,標準IO庫有很多細節,如緩衝區分配,優化塊長度執行IO等接下來讓我們來看看C庫中的標準IO 流和FILE物件 在上一章中所有IO都是圍繞檔案描述符進行的,當我們開啟一個檔案的時候,返回它的檔案描