进程之间是独立的,但是又是有联系的,他们可以使用管道、信号、socket、消息队列和共享内存来实现通信,那么我们先来看看进程之间如何使用管道:
#include
#include
#include
#include
#include
#include
int main()
{
pid_t pid;int fd[2];int ret=pipe(fd);if(ret==-1){printf("pipe error!\n");exit(1);}pid=fork();if(pid==-1){perror("fork error\n");exit(1);}else if(pid>0){waitpid(pid,NULL,WNOHANG);close(fd[1]);char buf[1024]={0};int len=0;len=read(fd[0],buf,sizeof(buf));printf("parent receive meassge:%s\n",buf);close(fd[0]);sleep(2);} else if(pid==0){
close(0);char * str="this is a message by child send!\n";write(fd[1],str,strlen(str)+1);close(fd[1]);sleep(2);
}return 0;
}
要注意几个点,管道是需要在进程创建之前在再创建的,如果在进程之后创建管道的话顺序就乱了,管道将不会生效,而且这个半双工过程,也就说我们一次只能通信一次,要么是a向b发信息,要么就是b向a,不能ab同时,所以我这里就拿父子进程来讲解;
首先我们创建管道(pipe函数):
int fd[2];
int ret=pipe(fd);
他需要一个int数组,两个元素,一个是读端(fd[0])一个是写端(fd[1]),pipe这个函数就是用来创建管道的,他的参数就是这个数组;
close(fd[1]);
char buf[1024]={0};
int len=0;
len=read(fd[0],buf,sizeof(buf));
printf("parent receive meassge:%s\n",buf);
close(fd[0]);
sleep(2);
在我们要写或者读一个内容的时候,如果是写我们就应该把读的管道描述符关闭,也就是这里的fd[0],同理如果是读的话就是关闭写了;
使用读写流也是read和write之前我讲过的,参数的话第一个就是描述符,第二个就是数据,第三个就是长度,这里注意read的返回值是读取到的真实长度,如果读取失败的话就是返回-1;如果想要父子之间一直保持通讯的话我们就不能关闭读写流了:
#include
#include
#include
#include
#include
#include
int main()
{
pid_t pid;int fd[2];int ret=pipe(fd);if(ret==-1){printf("pipe error!\n");exit(1);}pid=fork();if(pid==-1){perror("fork error\n");exit(1);}else if(pid>0){char buf[1024]={0};while(1){waitpid(pid,NULL,WNOHANG);int len=0;len=read(fd[0],buf,sizeof(buf));printf("parent receive meassge:%s\n",buf);sleep(2);char * str = "fighing ,child ,you are my hope!\n";write(fd[1],str,strlen(str)+1);sleep(2);}}else if(pid==0){char buf[1024]={0};while(1){char * str="fighting , parent , you are my example!\n";write(fd[1],str,strlen(str)+1);sleep(2);int len=0;len = read(fd[0],buf,sizeof(buf));sleep(2);printf("child receive message:%s\n",buf);}}return 0;
}
父子进程之间通讯要注意:
1、要先创建管道,再创建进程;2、父子进程要互相读写数据的时候就不需要关闭读写端,卡好时间即可;
匿名管道的含义:
匿名管道就是类似于 ls | wc –l这种由| 连接的一个或者多个命令,|的前一个命令的输出会作为后一个命令的输入;
父子之间通讯是共用一个管道,管道的两端只能进行读写操作中的一种,因此父子通讯时应该关闭父子进程中的一个文件描述符,比如在父进程中写操作,在子进程中读操作时,我们就应该使用close函数关闭父进程中的读端和子进程的写端;这样就可以通过向管道中读写数据来实现进程之间的通讯;
总结一下,结合之前的父子通讯内容,我们多加了循环和管道,循环的目的是为了可以更容易的看到结果,管道就是用来父子通讯的,父子通讯时只能一个写一个读,而且要将时间拿捏得死死的才能通讯成功,如果只是通讯一次的话我们就需要在一个进程进行读/写操时关闭另一个的写/读端;
上一篇:苹果推送和开发证书更新