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