进程的通信机制(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操作)

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

该通信方式可使用posix版本信号量机制来实现线程之间的同步与互斥

详情请见https://blog.csdn.net/qq_40170007/article/details/88083275

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值