1.通过打开两个管道来创建一个双向的管道。
2.管道是阻塞性的,当进程从管道中读取数据,若没有数据进程会阻塞。
3.当一个进程往管道中不断地写入数据但是没有进程去读取数据,此时只要管道没有满是可以的,但若管道放满数据则会报错。
不完整管道:
当读一个写端已经被关闭的管道时,在所有数据被读取后,read返回0,以表示到达了文件的尾部。
如果写一个独断已经被关闭的管道,则产生信号SIGPIPE,如果忽略该信号或捕捉该信号并从处理程序返回,则write返回-1,同时errno设置为EPIPE。
/*************************************************************************
> File Name: broken_pipe_r.c
> Author: CC
> Mail: 6828620@163.com
> Created Time: 2018年10月09日 星期二 21时34分46秒
************************************************************************/
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<sys/wait.h>
//read a pipe with write closed.
int main()
{
int fd[2];
if(pipe(fd) < 0){
perror("pipe error!\n");
exit(1);
}
pid_t pid;
if((pid = fork()) < 0){
perror("fork error!\n");
}else if(pid > 0){
//parent read
close(fd[1]);
sleep(4);//等待子进程完成,构造不完整管道。
while(1){
char c;
if(read(fd[0],&c,1) == 0){
printf("read end!\n");
break;
}else{
printf("%c",c);
}
close(fd[1]);
wait(0);
}
}else{
//child write
close(fd[0]);
char *s = "123456";
write(fd[1],s,sizeof(s));
close(fd[1]);
}
return 0;
}
/*************************************************************************
> File Name: broken_pipe_w.c
> Author: CC
> Mail: 6828620@163.com
> Created Time: 2018年10月09日 星期二 21时50分31秒
************************************************************************/
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<signal.h>
#include<unistd.h>
#include<errno.h>
//写一个读端已经被关闭的管道
void sig_handler(int signo)
{
if( signo == SIGPIPE){
printf("SIGPIPE occured!\n");
}
}
int main(void)
{
int fd[2];
if(pipe(fd) < 0){
perror("pipe error!\n");
exit(1);
}
pid_t pid;
pid = fork();
if(pid < 0){
perror("fork error!\n");
exit(1);
}else if(pid == 0){
//child
close(fd[1]);
close(fd[0]);
}else{
//parent 写入不完整管道中数据
sleep(2);
close(fd[0]);
if(signal(SIGPIPE,sig_handler) == SIG_ERR){
perror("signal sigpipe error!\n");
exit(1);
}
char *c = "123";
if(write(fd[1],c,sizeof(c)) != sizeof(c)){
perror("write error!\n");
fprintf(stderr,"%s,%s\n",strerror(errno),
(errno == EPIPE) ? "EPIPE" : "XXXXX");
}
close(fd[1]);
wait(0);
}
return 0;
}