无名管道(pipe)
在文件系统中没有实际的文件与之对应,存在内存里。
特点
1.只能用于亲缘进程间通信。
2.半双工的通信,具有固定的读端和写端。
3.管道是特殊文件,可以使用write、read、close操作,不支持sleep()操作。
无名管道的初始化
int pipefd[2] = {0};//读管道和写管道 int pipe(int pipefd[2]);
通过无名管道,实现父子进程的通信
#include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdlib.h> #define SIZE 128 int main(int argc,char *argv[]) { int pipefd[2] = {0};//读端和写端 int ret = pipe(pipefd);//无名管道的初始化 if(ret <0) { perror("pipe"); return -1; } pid_t pid = fork();//创建子进程 if(pid < 0) { perror("fork");//错误描述 return -1; } else if(pid == 0)//子进程 { close(pipefd[0]);//关闭读端 char buf[SIZE]; do{ fgets(buf,sizeof(buf),stdin);//键盘写入到buf里 int ret = write(pipefd[1],buf,sizeof(buf));//通过buf写入到管道中 if(ret < 0) { perror("write"); break; } }while(strncmp(buf,"quit",4) != 0);//“quit”退出 close(pipefd[1]);//关闭写端 exit(0);进程退出 } else//父进程 { close(pipefd[1]);//关闭写端 char buf[SIZE]; while(1) { int ret = read(pipefd[0],buf,sizeof(buf));//读管道中的数据 if(ret < 0) { perror("read"); break; } else if(ret ==0)//写端关闭,读端退出 { printf("write pipe closed\n"); break; } printf("buf:%s\n",buf); } close(pipefd[0]); exit(0); } return 0; }
注意:
1.当管道中没有数据时,读管道堵塞;
2.当写端关闭时,读管道会立即返回0;
3.当读端关闭,写端写管道时会出现管道破裂,并产生SIGPIPE信号。
有名管道 (fifo)
在文件系统中有实际的文件与之对应(管道文件)
特点
1.有名管道可以使用互不相关的两个进程互相通信。
2.有名管道可以通过路径名来指出,并且在文件系统中可见。
3.进程通过文件IO来操作有名管道。
4.有名管道遵循先进先出规则。不支持lseek()操作。
有名管道的初始化
int mkfifo(const char *pathname, mode_t mode);
pathname:管道文件路径
mode:文件权限
通过有名管道实现两个互不相关的进程互相通信
1.创建管道文件(myfifo),myfifo.c
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> int main(int argc,char *argv[]) { int ret = mkfifo("myfifo",0777); if(ret < 0 ) { perror("mkfifo"); return -1; } printf("mkfifo success"); return 0; }
2.写端写入数据,fifowrite.c
#include <stdio.h> #include<sys/types.h> #include <sys/stat.h> #include <wait.h> #include <fcntl.h> #include <string.h> #include <unistd.h> #define SIZE 128 int main(int argc,char *argv[]) { int fd = open("myfifo",O_WRONLY); if(fd < 0) { perror("open"); return -1; } char buf[SIZE]; do{ fgets(buf,sizeof(buf),stdin); int ret = write(fd,buf,sizeof(buf)); if(ret < 0) { perror("write"); return -1; } }while(strncmp(buf,"quit",4) != 0); close(fd); return 0; }
3.读端读数据,fiforead.c
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #define SIZE 128 int main(int argc,char *argv[]) { int fd = open("myfifo",O_RDONLY); if(fd < 0) { perror("open"); return -1; } char buf[SIZE]; while(1) { int ret = read(fd,buf,sizeof(buf)); if(ret <0) { perror("read"); break; } if(ret == 0) { printf("fifo write closed\n"); break; } else printf("buf:%s\n",buf); } close(fd); return 0; }
编译结果
1@buntu:~/day$ gcc fifowrite.c 1@ubuntu:~/day$ ./a.out hello I am fifowrite file
1@ubuntu:~/day$ gcc fiforead.c 1@ubuntu:~/day$ ./a.out buf:hello buf:I am fifowrite file fifo write closed