相对于有名管道,无名管道在文件目录树中没有文件描述符,所以无名管道要想完成进程间通讯,必须借助于父子进程在fork之前共享的文件描述符。相同的是,无名管道一个单向数据通道,进行半双工通讯。
无名管道的限制:无名管道只能用于有着亲缘关系的进程(父子进程、兄弟进程)之间。
无名管道的创建(父进程创建):int pipe(int fd[2]) ;f[0]指向管道的读端,f[1]指向写端。
使用:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <assert.h> #include <fcntl.h>cc #include <ctype.h> #define MAXLEN 256 int main() { int fd1[2]; int fd2[2]; char tmp[MAXLEN] = {0}; int check1 = pipe(fd1); int check2 = pipe(fd2); if( check1 == -1 || check2 == -1 ) { perror("check"); exit(0); } pid_t pid = fork(); if( pid == 0 )//子进程接收父进程的数据并处理数据,再传给父进程 { int i = 0 ; int co = 0 ; close(fd1[1]); close(fd2[0]); while(1) { co = read(fd1[0],tmp,MAXLEN); if( co == 0 || strncmp(tmp,"end",3) == 0 ) break ; for( i = 0 ; i < co ;++i ) { if( islower(tmp[i]) ) tmp[i] = tmp[i] - 'a' + 'A'; } write(fd2[1],tmp,strlen(tmp)); memset(tmp,0,MAXLEN); } close(fd1[0]); close(fd2[1]); } else//父进程接收用户输入数据,传给子进程,再接收子进程处理的数据输出 { close(fd1[0]); close(fd2[1]); while(1) { printf("father input:"); fgets(tmp,MAXLEN-1,stdin); write(fd1[1],tmp,strlen(tmp)-1); if( strncmp(tmp,"end",3) == 0 ) break ; memset(tmp,0,MAXLEN); read(fd2[0],tmp,MAXLEN); printf("father output:%s\n",tmp); } close(fd1[1]); close(fd2[0]); } exit(0) ; }
运行结果:
往无名管道读写注意:
一、父子进程运行不能保证先后顺序。
扫描二维码关注公众号,回复:
31475 查看本文章
二、跟有名管道一样是半双工,所以一个进程不要同时对一个无名管道进行读+写。