进程的通信机制(IPC)

(一)使用管道进行通信

管道是指用于连接一个读进程和一个写进程以实现他们之间进行通信的共享文件。

管道机制必须提供以下三方面的协调能力:互斥、同步、和确定对方存在

管道操作,只能采用半双工通信,即某一时刻只能单向传输。要实现父子双方之间相互通信,则要定义两个管道。

下面则是实现的父子双方使用管道进行通信的实例:

#include<unistd.h>
#include<sys/types.h>
#include<stdio.h>
#include<stdlib.h>
#include<wait.h>
int main()
{
  pid_t pid;
  int fd1[2];
  int fd2[2];
  int x;
  if(pipe(fd1)<0)//父进程先创建管道文件1
        {printf("error pipe\n");
         exit(1);}
  if(pipe(fd2)<0)//父进程创建管道文件2
        { printf("error pipe\n");
         exit(1);}
  if((pid=fork())<0)//父进程创建子进程
        {printf("error fork\n");
         exit(1);}
  else if(pid==0)//子进程关闭管道文件1的写端口,和管道文件2的读端口
       {
         close(fd1[1]);
         close(fd2[0]);
         while(x<=9)
         {
          read(fd1[0],&x,sizeof(int));//从管道1的读端口读取数据
          printf("child %d read:%d\n",getpid(),x);
          x=x+1;
          write(fd2[1],&x,sizeof(int));//向管道2的写端口写数据
         }
          close(fd1[0]);//关闭读写端口
          close(fd2[1]);
          exit(0);
      }
  else
     {
      close(fd1[0]);//子进程,关闭管道文件1的写端口,和管道文件2的读端口
      close(fd2[1]);
      x=1;
      while(x<=9)
      {
       write(fd1[1],&x,sizeof(int));//向管道文件1的写端口写数据
       read(fd2[0],&x,sizeof(int));//向管道文件2的读端口写数据
       printf("parent %d read:%d\n",getpid(),x);
       x=x+1;
       }
       close(fd1[1]);
       close(fd2[0]);
       wait(NULL);
       exit(0);
     }

}

(二)消息队列实现通信

在消息传递的通信中,信息是以消息为单位进行传递的。

直接通信方式:发送进程直接把消息发送给接收进程,并将它挂在接收进程的消息缓冲区队列上,接收进程则是从消息缓冲区中取消息的。

下面实例中,消息我们定义了结构体进行存放

#include<unistd.h>
#include<sys/types.h>
#include<sys/msg.h>
#include<stdio.h>
#include<wait.h>
#include<sys/ipc.h>
#include<stdlib.h>
#include<string.h>
struct message
{
  long msg_type;
  char msg_text[256];
};//定义结构体,存放消息
int main()
{
  pid_t pid;
  key_t key;
  int qid,n;
  struct message msg;
  if((key=ftok("/home/yinyunhong/shiyan5/msgfile",1))==-1)//需要产生ID值,该ID值由ftok()函数产生
   { perror("ftok");
     exit(1);
   }
  if((qid=msgget(key,IPC_CREAT|0666))==-1)
  { perror("msgget");
    exit(1);
  }
  msg.msg_type=2;
  pid=fork();//创建子进程
  if(pid<0)
     {printf("error fork!\n");
      exit(1);
     }
  else if(pid==0)//子进程先清空缓冲区,再接收消息
  {
   memset(msg.msg_text,0,256);
   if((n=msgrcv(qid,&msg,sizeof(msg.msg_text),2,0))<0)
   {
    perror("msgrcv");
    exit(1);
   }   
   else
   {
    printf("Child:Receiving from the message queue:%s\n",msg.msg_text);
    exit(0);
    }
  }
  else//父进程将消息拷贝到消息结构体中,进行发送消息
  {
    strcpy(msg.msg_text,"This is the input");
    if(msgsnd(qid,&msg,strlen(msg.msg_text),0)==0)
    {
      printf("Parent:Send to the message queue successfully!\n");
      printf("The message sent is:%s\n",msg.msg_text);
    }
    wait(NULL);//父进程等待子进程的结束
    if(msgctl(qid,IPC_RMID,NULL)<0)
    {
     perror("msgctl IPC_RMID");
     exit(1);
    } 
    else
    {
     printf("Parent delete msg successfully\n");
     exit(0);
    }
  } 
 return 0;    
} 

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

三、共享内存的通信方式

共享内存是指在通信进程之间存在一块可直接访问的共享空间,通过对该共享空间进行读写操作(需使用同步互斥工具,如p,v操作)

扫描二维码关注公众号,回复: 5405099 查看本文章

该方式是不需要经过通过用户内核实现的,而其它方式则需要由用户内核进行实现。该共享空间是由系统开辟出来供进程进行共同访问的。

猜你喜欢

转载自blog.csdn.net/qq_40170007/article/details/88094406
今日推荐