进程间的通信

一个进程传递信息给另一个进程
一、 进程通信的类型
1.共享存储器系统
(1)基于共享数据结构的通信方式
系统只提供共享存储器,程序员需定义数据结构和进程间同步的处理,效率较低,属于低级通信

(2)基于共享存储区的通信方式
进程之间通过对共享存储区的读写交换信息,只需调用方法即可,底层均由OS管理(也可自己进行同步处理),属于高级通信
例:两台主机之间QQ消息的传送
在发送端开辟一个缓存区,存放发送的数据,通过物理媒体的传递通过网卡到接收端的缓冲区。
问题:为什么QQ发送的消息不会出现在浏览器上?
解答:每个应用程序都有自己的端口,通过端口找到再各自电脑上的缓冲区,从中发送或者获取数据

2.管道通信方式
用于连接一个读进程和一个写进程的共享文件(pipe文件)
管道的协调能力通过实现互斥同步以及确定对方是否存在来协调读写进程的运行

例:

 //根据输出的信息可以体会到两个窗口在交错有秩的执行
 
 //读管道
 int main(int argc,char *argv[]) {
  if(argc!=2) {
   printf("not enough params,give pipefile name\n");
   exit(1);
  }
  
  char *pipefile;
  pipefile=argv[1];
  char buf[100];
  int fd,i;
  
  printf("read open namedpipe!\n");
  fd=open(pipefile,O_RDONLY,0);    //只有当读和写的两个open都是执行的时候才可以继续执行,否则将等待
  printf("ok! namedpipe opened for read!\n");
  
  i=read(fd,buf,100);       //当没有写操作执行时才可读,否则等待
  buf[i]=0;
  printf("ok! reaed from namedpipe: %s!\n",buf);  
  
  return 0;
 }
 
 //写管道
 int main(int argc,char *argv[]) {
  if(argc!=2) {
   printf("not enough params,give pipefile name\n");
   exit(1);
  }
  
  char *pipefile;
  pipefile=argv[1];
  int fd;
  char *test="test strings!";
  
  printf("open namedpipe --%s for write!\n",pipefile);
  fd=open(pipefile,O_WRONLY,0);        //只有当读和写的两个open都是执行的时候才可以继续执行,否则将等待
  printf("ok! namedpipe --%s opened for write!\n",pipefile);
  
  sleep(10);
  printf("write wake up! hahaha!\n");
  write(fd,test,strlen(test));
  printf("OK! namedpipe write successfully!\n");
  
  exit(0);
 }
 

3.客户端/服务器系统
远程过程调用RPC:请求端-远程服务器-应答端-远程服务器-请求端 实现消息的传递

4.消息传递系统
进程以格式化的消息为单位,将数据封装在消息中,并利用操作系统提供的一组通信命令,进行消息传递(单机中:操作系统底层编程中的消息传递系统调用)

(1)直接通信方式
利用OS中的发送原语,直接把消息发送给目标进程
消息传递系统的实现:
①直接通信原语:
send(receiver,message);
receiver(sender,message);
②消息的格式:单机环境中,较简单,可采用等长或变长消息合适
?进程的同步方式:
发送进程阻塞,接受进程阻塞:用于进程之间紧密同步,发送进程和接受进程无缓冲时
发送进程不阻塞,接受进程阻塞:接受进程收到发送进程的消息时被唤醒
发送进程不阻塞,接受进程不阻塞:仅当发成某时间使它无法继续运行时,才把自己阻塞起来等待
④通信链路:单机:系统会自动建立一条链路,分为单向通信链路和双向通信联络
例:

type ProcessControlBlock=record
   ...
   struct message_buffer *mq;    //消息队列队首指针
   semaphore mutex;       //消息队列互斥信号量
   semaphore sm;        //消息队列资源信号量
   ...
 end
 
 void send(receiver a) {
    getbuf(a.size,i);             //根据a.size申请缓冲区
    i.sender=a.sender;     
    i.size=a.size;      //将发送区的信息复制到缓冲区中
    copy(i.text,a.text);
    
    //表示i不指向下一个
    i.next=0;
    getid(PCB set,receiver.j);   //获取接受进程内部标识符
       
    //防止别的进程插入
    wait(j.mutex);      
       insert(j.mq,i);      //插入到目标消息队列中
       signal(j.mutex);
       
       signal(j.sm);       //释放一个资源
   }
   
 void receive(b) {
  j=internal name;      //j为接受进程内部标识符
  wait(j.sm);
  
  //实现互斥,防止别的资源访问i缓冲区
  wait(j.mutex);
  remove(j.mq,i);
  signal(j.mutex);
  
  b.sender=i.sender;
  b.size=i.size;
  copy(b.text,i.text);
  releasebuf(i);
 }

图示:
在这里插入图片描述
(2)间接通信方式
通过共享中间实体(邮箱)的方式进行消息的发送和接受
邮箱的类型:
①私有邮箱:拥有者可以读取消息,其他用户则只能发送到该邮箱
②公用邮箱:进程可将发送信息到邮箱中,也可通过邮箱提取信息
?共享邮箱:拥有者和共享者都有权从邮箱中取走发送给自己的信息

在利用邮箱通信时,在发送进程和接受进程之间有四种关系:
1.一对多
2.多对多
3.多对一
4.一对一

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值