管道的一些读写规则

 

当没有数据可读时
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

 

你可能感兴趣的:(管道,读写规则)