Linux中的进程通信方式有很多种,首先来介绍一下管道。管道的特点是只能用在有“亲缘”关系的父子进程之间。
管道的创建:
#include<stdio.h>
#include<stdlib.h>
int fd[2];
int ret = pipe(fd);
if(ret == -1)
{
perror("pipe.");
return -1;
}
父子进程之间的简单通信,父进程发送一句话给子进程:
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<string.h>
#include<stdlib.h>
int main()
{
int fd[2];
int ret = pipe(fd);
if(ret == -1)
{
perror("pipe.");
return -1;
}
pid_t pid = fork();
if(pid == 0)
{
char buffer[256];
close(fd[1]);//child用[0]来读,首先关闭[1]
read(fd[0],buffer,256);
close(fd[0]);//读完后关闭[0]
printf("parent -> %s\n",buffer);
exit(0);
}
else if(pid > 0)
{
char *words = "Rome was not built in a day.";
close(fd[0]);//parent用[1]端来写,首先关闭[0]
write(fd[1],words,strlen(words) + 1);
close(fd[1]);//写完后关闭[1]
int status;
wait(&status);
}
else
{
perror("fork.");
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/a92fbfca660b4fcd6865eea2ccf8d62f.png)
从结果可以看出,父进程中的一个字符串,通过管道送到了子进程,并且子进程打印了接收到的字符串。
这可以说是一个管道的最基本的例子,里面用到了pipe(),close(),read(),write()应该熟练掌握。
如果要实现父进程向子进程发消息,并且子进程也可以向父进程发消息。由于管道是半双工通信(即Half duplex Communication,是指在通信过程的任意时刻,信息既可由A传到B,又能由B传A,但只能有一个方向上的传输存在--摘自百度百科)所以需要用到两根管道来实现。
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/wait.h>
int main()
{
char * parent_talk[]={"Hello","Can you tell me,What's the time?","OMG,Bye",NULL};
char * child_talk[] = {"Hi","No problem","Bye",NULL};
int fd1[2],fd2[2];
int ret1,ret2;
ret1 = pipe(fd1);
ret2 = pipe(fd2);
if(ret1 == -1 || ret2 == -1)
{
perror("pipe.");
exit(1);
}
pid_t pid = fork();
if(pid == 0)
{
close(fd1[1]);
close(fd2[0]);
char buffer[256];
int j = 0;
char *talk = child_talk[j];
while(talk != NULL)
{
read(fd1[0],buffer,256);
write(fd2[1],talk,strlen(talk) + 1);
printf("parent -> %s\n",buffer);
++j;
talk = child_talk[j];
}
close(fd1[0]);
close(fd2[1]);
}
else if(pid > 0)
{
close(fd1[0]);
close(fd2[1]);
char buffer[256];
int i = 0;
char *talk = parent_talk[i];
while(talk != NULL)
{
write(fd1[1],talk,strlen(talk) + 1);
read(fd2[0],buffer,256);
printf("child -> %s\n",buffer);
++i;
talk = parent_talk[i];
}
close(fd1[1]);
close(fd2[0]);
int status;
wait(&status);
}
else
{
perror("fork.");
}
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/2bb05621e40807beef7b80d754a6ee6c.png)
分析运行的结果:父进程先write再read,子进程先read再write,才能得到预计的效果。如果两个顺序一样的话,执行就出了问题?
![](https://i-blog.csdnimg.cn/blog_migrate/8212c755f9ede6edc603ebca671da4e3.png)
随着学习的过程会逐渐补充blog。