内容: 记录进程间通信的其中一种方式:管道
管道特点:
原理: 管道实际是用于进程间通信的一段共享内存,一个进程在向管道写入数据后,另一进程就可以从管
道的另一端将其读取出来。
特点:
1、管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道。
2、只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程)。
比如fork或exec创建的新进程,在使用exec创建新进程时,需要将管道文件描述符作为参数传递给exec
创建的新进程。父进程与使用fork创建的子进程直接通信时,发送数据进程关闭读端,接受数据进程关闭
写端。
3、单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它
不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。
4、数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道
缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。
机制:
管道是由内核管理的一个缓冲区。管道的一端连接一个进程的输出。这个进程会向管道中放入信息。管道
的另一端连接一个进程的输入,这个进程取出被放入管道的信息。一个缓冲区不需要很大,它被设计成为
环形的数据结构,以便管道可以被循环利用。当管道中没有信息的话,从管道中读取的进程会等待,直到
另一端的进程放入信息。当管道被放满信息的时候,尝试放入信息的进程会等待,直到另一端的进程取出
信息。当两个进程都终结的时候,管道也自动消失。
不足之处:
1、管道只能在本地计算机中使用,而不可用于网络间的通信。
2、管道只能单向
3、管道不可以在无血缘关系的进程间使用
管道接口:
#include <unistd.h>
int pipe(int pipefd[2]);
管道代码:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main(void){
int fd[2];//作为传入参数,接收文件描述符
pid_t pid;
int ret = pipe(fd);
if(-1 == ret){
perror("create pipe error!\n");
exit(1);
}
pid = fork();
if(-1 == pid){
perror("fork error:");
exit(1);
}else if(0 == pid){
//管道是单向的,需要每人掌握一端,但不能一个进程同时掌握读写两端
//规定,fd[0]为读端,fd[1]为写端
close(fd[1]);
char buf[100];
ret = read(fd[0],buf,sizeof(buf));
if(0 == ret){
printf("waitting.......\n");
}
write(STDOUT_FILENO,buf,ret);
}else{
close(fd[0]);
write(fd[1],"send message from father:hello world\n",strlen("send message from father:hello world\n"));
sleep(1);
}
return 0;
}
**结果:**成功的读出父进程写的数据
记得: 单进程测试的时候不需要关闭读写端,父子进程间通信需要各自关闭一端
大四学生一枚,如果文章有错误的地方,欢迎在下方提出,每条评论我都会去认真看并回复,同时感谢指正的前辈。有喜欢C/C++,linux的同学欢迎私信一起讨论学习。