赞
踩
管道是一种最基本的IPC机制,作用于有血缘关系的进程之间,完成数据传递。调用pipe系统函数即可创建一个管道。有如下特质:
1. 其本质是一个伪文件(实为内核缓冲区)
2. 由两个文件描述符引用,一个表示读端,一个表示写端。
3. 规定数据从管道的写端流入管道,从读端流出。
管道的原理: 管道实为内核使用环形队列机制,借助内核缓冲区(4k)实现。
管道 分为 标准流管道,无名管道(PIPE),命名管道(FIFO)
① 数据自己读不能自己写。
② 数据一旦被读走,便不在管道中存在,不可反复读取。
③ 由于管道采用半双工通信方式。因此,数据只能在一个方向上流动。
其中 无名管道 ’标准管道 只能在有公共祖先的进程间使用管道。
demo 两个子进程 写父进程读
- #include <stdio.h>
-
- #include <unistd.h>
-
- #include <sys/wait.h>
-
- #include <string.h>
-
- #include <stdlib.h>
-
- int main(void)
- {
-
- pid_t pid;
-
- int fd[2], i, n;
-
- char buf[1024];
-
- int ret = pipe(fd);
-
- if (ret == -1)
- {
-
- perror("pipe error");
-
- exit(1);
- }
-
- for (i = 0; i < 2; i++)
- {
-
- if ((pid = fork()) == 0)
- {
- if (i == 0)
- {
-
- close(fd[0]);
-
- write(fd[1], "1.hello\n", strlen("1.hello\n"));
- }
- else if (i == 1)
- {
-
- close(fd[0]);
-
- write(fd[1], "2.world\n", strlen("2.world\n"));
- }
- break;
- }
-
- else if (pid == -1)
- {
-
- perror("pipe error");
-
- exit(1);
- }
- }
-
- if (pid > 0)
- {
-
- close(fd[1]); //父进程关闭写端,留读端读取数据
-
- // sleep(1);
-
- n = read(fd[0], buf, 1024); //从管道中读数据
-
- write(STDOUT_FILENO, buf, n);
-
-
- for (i = 0; i < 2; i++) //两个儿子wait两次
-
- wait(NULL);
- }
-
- return 0;
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
结果
demo
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #define BUFSIZE 1024
- int main()
- {
- FILE *fp;
- char *cmd = "printenv";
- char buf[BUFSIZE];
- buf[BUFSIZE-1] = '\0';
- if((fp=popen(cmd,"r"))==NULL)
- perror("popen");
-
- while((fgets(buf,BUFSIZE,fp))!=NULL)
- printf("%s",buf);
-
- pclose(fp);
- exit(0);
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
上述管道虽然实现了进程间通信,但是它具有一定的局限性:首先,这个管道只能是具有血缘关系的进程之间通信;第二,它只能实现一个进程写另一个进程读,而如果需要两者同时进行时,就得重新打开一个管道。
为了使任意两个进程之间能够通信,就提出了命名管道(named pipe 或 FIFO)
不支持seek 先进先出
原型
fifo_read.c
- #include<stdio.h>
- #include<stdlib.h>
- #include<errno.h>
- #include<fcntl.h>
- #include<sys/stat.h>
-
- int main()
- {
- int fd;
- int len;
- char buf[1024];
-
- if(mkfifo("fifo1", 0666) < 0 && errno!=EEXIST) // 创建FIFO管道
- perror("Create FIFO Failed");
-
- if((fd = open("fifo1", O_RDONLY)) < 0) // 以读打开FIFO
- {
- perror("Open FIFO Failed");
- exit(1);
- }
-
- while((len = read(fd, buf, 1024)) > 0) // 读取FIFO管道
- printf("Read message: %s", buf);
-
- close(fd); // 关闭FIFO文件
- return 0;
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
fifo_read.c
- #include<stdio.h>
- #include<stdlib.h> // exit
- #include<fcntl.h> // O_WRONLY
- #include<sys/stat.h>
- #include<time.h> // time
-
- int main()
- {
- int fd;
- int n, i;
- char buf[1024];
- time_t tp;
-
- printf("I am %d process.\n", getpid()); // 说明进程ID
-
- if((fd = open("fifo1", O_WRONLY)) < 0) // 以写打开一个FIFO
- {
- perror("Open FIFO Failed");
- exit(1);
- }
-
- for(i=0; i<10; ++i)
- {
- time(&tp); // 取系统当前时间
- n=sprintf(buf,"Process %d's time is %s",getpid(),ctime(&tp));
- printf("Send message: %s", buf); // 打印
- if(write(fd, buf, n+1) < 0) // 写入到FIFO中
- {
- perror("Write FIFO Failed");
- close(fd);
- exit(1);
- }
- sleep(1); // 休眠1秒
- }
-
- close(fd); // 关闭FIFO文件
- return 0;
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。