无名管道
pipe()创建管道,半双工,所以在使用时候close()另外一个;
适合在有血缘关系的进程中使用,如 父子进程;
1.简单应用:
fork()函数创建子进程
pipe()函数创建管道
read()和write()函数完成读写
c
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
int fd[2];
if(pipe(fd)==-1)return -1; //创建管道,返回-1表示失败
if(fork()==0){
//子进程,写入
close(fd[0]);
while(1)
{
char buf[128];
ssize_t len=read(0,buf,128); //read默认会阻塞,等待输入
buf[len]=0;
printf("子进程写入数据%s\n",buf);
write(fd[1],buf,128);
}
_exit(0);
}
//父进程
close(fd[1]);
for (int i = 0; i < 3; i++)
{
char buf[128];
ssize_t len=read(fd[0],buf,128);
buf[len]=0;
printf("主进程收到的内容:%s\n",buf);
}
close(fd[0]);
//关闭读后,子进程会 收到信号,会退出;
printf("main over\n");
return 0;
}
2.父子进程实现命令中管道的功能,如:ps -A | grep bash
dup2()函数完成文件标识符的重定向
execlp()函数开始一个新的进程执行其中的命令
c
int main()
{
int fd[2];
if(pipe(fd)==-1) return -1; //管道创建失败
if(fork()==0)
{
//子进程-读取数据从管道中
close(fd[1]);
dup2(fd[0],0);//管道的内容将被视为标准键盘输入
execlp("grep","grep","bash",NULL);//grep命令可以将从键盘输入的内容进行过滤
_exit(0);//子进程退出
}
//父进程-写入到管道中
close(fd[0]);
dup2(fd[1],1);//标准输出将被视为 管道输入内容
execlp("ps","ps","-A",NULL);//执行命令输出
return 0;
}
有名管道
会以文件出现,内容出现在内存中
适合用于没有血缘关系的多个进程中
1.两个进程通信,demo2与demo1
默认阻塞模式下:
被阻塞的条件:管道两边打开,但是没有内容时;
在指定为非阻塞模式时:
int fd =open("fifo1",O_WRONLY|O_NONBLOCK);增加O_NONBLOCK模式,表示不阻塞,但是读进程退出后,写进程会退出
demo1.c
c
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
int main(int argc,char *argv[]){
if(mkfifo("fifo1",0666)!= 0){ //创建有名管道,用完需要删掉
perror("mkfifo");
return -1;
}
printf("fifo1已经创建\n");
int fd = open("fifo1",O_RDONLY); //如果没有第二个以只写打开,将持续阻塞
printf("--open fifo1--\n");
while(1){
char buf[128];
ssize_t len =read(fd,buf,128);
buf[len]=0;
printf("读取数据为:%s\n",buf);
sleep(2);
}
return 0;
}
demo2.c
c
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
int main(int argc,char *argv[])
{
int fd =open("fifo1",O_WRONLY);//int fd =open("fifo1",O_WRONLY|O_NONBLOCK);增加O_NONBLOCK模式,表示不阻塞,但是读进程退出后,写进程会退出
//被阻塞的条件:管道打开且没有数据时
while(1){
char buf[128];
ssize_t len=read(0,buf,128);
buf[len]=0;
write(fd,buf,len);
if(strncmp(buf,"sxit",4)==0)break;
}
close(fd);
return 0;
}