天天看點

标準IO緩沖與fork問題

系統函數read和write是不帶緩沖的,而c的标準io函數是帶緩沖的,

(1)當io函數與stderr相連時 是不帶緩沖的(為了錯誤能夠快速輸出)

(2)當與stdin和stdout相連是行緩沖的(即遇到換行符就輸出)

(3)與其他的相連都是全緩沖的(緩沖區滿了才輸出)

可以用一個小例子試一下,參考 《unix環境進階程式設計》 8.1

# include <stdio.h>
# include <apue.h>
int globvar = 6;
char buf[] = "a write to stdtou\n";


int main(){
    int var;
    pid_t pid;


    var = 88; 
    char *ma_buf = (char *) malloc(100);
    strcpy(ma_buf,"hahahaha");
    if(write(STDOUT_FILENO,buf,sizeof(buf)-1) != sizeof(buf)-1)
        err_sys("write error");
    printf("before fork _huanhang\n");
    printf("before fork :");


    if( (pid = fork()) < 0 ){
        err_sys("fork error");
    } else if(pid == 0){ 
        var = 88; 
        globvar ++; 
        printf("child: ma_buf = %s\n",ma_buf);
    } else {
        sleep(2);
        printf("parent: ma_buf = %s\n",ma_buf);
    }   


    printf("pid = %ld, globvar = %d, var = %d\n",(long)getpid(),globvar,var);


}
           

結果:

[email protected]:~/code$ gcc 8_1.c 
<strong>[email protected]:~/code$ ./a.out   //  1</strong>
a write to stdtou
before fork _huanhang<span style="white-space:pre">	</span>
before fork :child: ma_buf = hahahaha
pid = 20593, globvar = 7, var = 88
before fork :parent: ma_buf = hahahaha
pid = 20592, globvar = 6, var = 88
<strong>[email protected]:~/code$ ./a.out > tmp   // 2
[email protected]:~/code$ cat tmp</strong>
a write to stdtou
before fork _huanhang
before fork :child: ma_buf = hahahaha
pid = 20595, globvar = 7, var = 88
before fork _huanhang
before fork :parent: ma_buf = hahahaha
pid = 20594, globvar = 6, var = 88
           

write 不帶緩沖是以1 2都指數出一次

printf “before fork _huanhang”在1中與終端stdout相連是行緩沖的,是以在1中隻輸出一次

而在2中是與tmp相連的是全緩沖的,fork之後會把緩沖區一起複制,是以before fork _huanhang會輸出兩次

printf “before fork”因為沒有遇到換行符 是以在1,2中都輸出兩次