管道的一些讀寫規則

 

當沒有數據可讀時
O_NONBLOCK disable:read調用阻塞,即進程暫停執行,一直等到有數據來到爲止。
O_NONBLOCK enable:read調用返回-1,errno值爲EAGAIN。


當管道滿的時候
O_NONBLOCK disable: write調用阻塞,直到有進程讀走數據
O_NONBLOCK enable:調用返回-1,errno值爲EAGAIN
如果所有管道寫端對應的文件描述符被關閉,則read返回0
如果所有管道讀端對應的文件描述符被關閉,則write操作會產生信號SIGPIPE
當要寫入的數據量不大於PIPE_BUF時,linux將保證寫入的原子性。
當要寫入的數據量大於PIPE_BUF時,linux將不再保證寫入的原子性。

 

案例驗證:O_NONBLOCK enable:read調用返回-1,errno值爲EAGAIN。

$ cat ./apue.h

#ifndef _APUE_H_
#define _APUE_H_

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <assert.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <signal.h>
#include <sys/time.h>

void err_exit(char *m){
        perror(m);
        exit(EXIT_FAILURE);
}

#endif /* _APUE_H_ */

 

主程序
#include "./apue.h"

int main(void){
    int fd[2];
    if(pipe(fd)==-1){
        err_exit("pipe error");
    }
    pid_t pid=fork();
    if(pid==-1)
        err_exit("fork error");
    if(pid==0){
        close(fd[0]);
        write(fd[1], "hello", 5);
        close(fd[1]);
        exit(EXIT_SUCCESS);
    }
    close(fd[1]);
    char buf[10]={0};
    int flags=fcntl(fd[0], F_GETFL);
    fcntl(fd[0], F_SETFL, O_NONBLOCK | flags);
    int ret=read(fd[0], buf, 10);
    if(ret==-1)
        err_exit("read error");
    printf("buf=%s\n", buf);
    return 0;
}

 

編譯執行,返回

read error: Resource temporarily unavailable

 

 

驗證管道容量程序


#include "./apue.h"

int main(void){
    int fd[2];
    int count,ret,flags;
    count=0;
    if(pipe(fd)==-1)
        err_exit("pipe error");

    flags=fcntl(fd[1], F_GETFL);
    fcntl(fd[1], F_SETFL, flags|O_NONBLOCK);

    while(1){
        ret=write(fd[1], "A", 1);
        if(ret==-1){
            printf("%s\n",strerror(errno));
            break;
        }
        count++;
    }
    printf("count=%d\n", count);
    return 0;
}

 

返回

Resource temporarily unavailable
count=65536

結論:管道容量爲64KB

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章