當沒有數據可讀時
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