1.在无名管道里面,只能用于具有亲缘关系的父子进程。这是因为只有子进程才具有和父进程一样的管道,他们是共用
2.有名管道:
在文件系统中课件
可以通过文件io操作有名管道
遵循先进先处
创建有名管道的函数:mkfifo()只是创建,没有打开读端写端,这是和pipe的区别
3.有名管道使用时注意的地方:
open()函数flag以O-RDONLY打开,只能打开有名管道的读端,以O-WRONLY,只能打开有名管道的写端;
open()函数flag以O-RDWR方式打开,将打开管道的读写端,只有同时打开管道的读端和写端,有名管道才被真正的打开,只打开读端或者写端open()函数是会出现阻塞的。
创建管道fifo
if(mkfifo("./fifo",0666)<0)//第一个参数想要创建的文件的路径,第二个参数是指创建文件的全像
{
perror("create wrong");
exit(1);
}
这个以文件打开方式打开的有名管道的写端,这两个文件分别在两个终端下同时运行
出现结果:before
write open
after write open
writeno:6!!!Hello World!!!
before
write open
after write open
writeno:6!!!Hello World!!!
这也就是说成功进行了有名管道的读写操作
/*
============================================================================
Name : namepipewrite.c
Author :
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
int main(void) {
int fd;
puts("before write open");
fd=open("./fifo",O_RDWR);
puts("after write open");
if(fd==-1)
{
perror("open wrong!");
exit(1);
}
char buf[10]="hello!";
int writeno=write(fd,buf,strlen(buf));
if(writeno==-1)
{
perror("write wrong");
exit(1);
}
printf("writeno:%d",writeno);
puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
return EXIT_SUCCESS;
}
这个是以文件打开方式实现的有名管道的读端
/*
============================================================================
Name : mkfifo.c
Author :
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
int main(void) {
int fd;
char buf[10];
puts("before read open");
if((fd=open("./fifo",0666))==-1)
{
perror("open error");
exit(0);
}
puts("after read open");
int readno=read(fd,buf,10);
if(readno==-1)
{
perror("read error!");
exit(1);
}
printf("readno:%d ",readno);
// if(mkfifo("./fifo",0666)<0)//第一个参数想要创建的文件的路径,第二个参数是指创建文件的全像
// {
// perror("create wrong");
// exit(1);
// }
return EXIT_SUCCESS;
}
有名管道实验:
1.创建管道
/*
============================================================================
Name : namepipeconnnect.c
Author :
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
int main(int argc,char **argv)
{
if(argc<2)
{
puts("you should enter 2");
puts("like :1 2 ");
exit(1);
}
FILE *fp;
if(mkfifo(argv[1],0666)<0)
{
perror("create name pipe wrong!");
exit(1);
}
return EXIT_SUCCESS;
}
2.write:
#include <stdio.h>
#include <stdlib.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<errno.h>
#include<fcntl.h>
#include<string.h>
void again(int fd,const char *buf,int * writeno)
{
if((*writeno=write(fd,buf,strlen(buf)))<0)
{
if(errno==EINTR)
{
again(fd,buf,writeno);
}
else
{
fprintf(stderr,"write failed on fifo:%s",strerror(errno));
}
}
}
int main(int argc,char **argv)
{
puts("je");
char buf[1024];
int writeno;
if(argc<2)
{
puts("you should enter 2");
puts("like:1 2");
exit(1);
}
int fp;
perror("caught write signal");
puts("je");
if((fp=open(argv[1],O_RDWR))==-1)
{
perror("write pipe wrong!");
exit(1);
}
puts("je");
while(fgets(buf,1024,stdin))
{
again(fp,buf,&writeno);
}
return 0;
}
3.read:
#include <stdio.h>
#include <stdlib.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<errno.h>
#include<fcntl.h>
#include<string.h>
void again(int fd,char *buf,int *readno)
{
if((*readno=read(fd,buf,1024))<0)
{
if(errno==EINTR)
{
again(fd,buf,readno);
}
else
{
fprintf(stderr,"read failed on :%s\n",strerror(errno));
}
}
else if(readno==0)
{
fprintf(stderr,"peer closed fifo.\n");
exit(1);
}
else
{
buf[*readno]='\0';
fprintf(stdout,"read %d butes from fifo:%s",readno,buf);
}
}
int main(int argc,char **argv)
{
int fp;
int readno;
char buf[1024];
if(argc<2)
{
puts("you should enter 2");
puts("like:1 2");
exit(1);
}
if((fp=open(argv[1],O_RDONLY))==-1)
{
perror("open read pipe wrong");
exit(1);
}
puts("create read Okay");
puts("caught read sgnal");
while(1)
{
again(fp,buf,&readno);
}
return 0;
}
现在终端上编译创建pipe程序
然后在一个终端上运行write
在另一个终端上运行read,则当在write里面写入时,在read里面会相应的输出