进程通信(IPC)——实现共享内存

        今天分享一下,进程通信(IPC——实现共享内存。

       我们知道进程间通信的本质是让不同的进程看到同一内存。这之前我们用了不同的方式(管道,消息队列,信号量等等)让进程间能够通信,现在我们尝试着在内存共享区中开辟一段内存,即共享内存,让需要通信的两个进程通过页表映射到共享内存上,从而各自得到一个能映射到这段共享内存的虚拟地址的指针,进程间即可通过含有虚拟地址的指针对共享内存进行相应读写操作了。

      实现共享内存的步骤:

  1)创建共享内存(得到共享内存),使用shmget。

  2)把共享内存挂接到各自进程,使用shmat。

  3)各个进程对共享进程相应操作。

  4)使用完毕后,取消共享内存对各自进程的挂接,使用shmdt。

  5)最后,销毁共享内存,使用shmctl。注:谁创建谁销毁。


    注:若不懂使用方式man一下,直接看文档。就不详细介绍共享内存相关函数的使用了。

    由于共享内存也是随内核的,不主动释放会一直存在于内核中。所以系统有查看共享类存的相应命令,截图如下:


       由于是在内存共享区中开辟一段内存,所以共享类存的速度是进程通信所有方法中最快的,但是它的缺点是:共享内存没有自带进程的同步与互斥,所以可能会导致进程间信息冲突。所有一般情况下,共享内存都会和信号量结合在一起用,这个以后有时间会补写一个完整的,今天就这样吧!


    源代码和运行结果如下:

comm.h 

 #ifndef _COMM_H_
   #define _COMM_H_
   
   #include<stdio.h>
   #include<sys/types.h>
   #include<sys/ipc.h>
   #include<sys/shm.h>
   
   union semu{
        int val;
        struct semid_ds* buf;
        unsigned short* array;
        struct seminfo* _buf;
        };
        
  #define PATHNAME "."
  #define PROJ_ID 0X6666
 
  int GreatShm(int nums);
  int GetShm(int nums);
  int DestoryShm(int semid);
  
  #endif

ret.h   

#include"comm.h"
   
   int Common(int nums,int flags){
       key_t keys = ftok(PATHNAME, PROJ_ID);
       if(keys<0){
           perror("ftok");
           return -3;
       }
       int shmid = shmget(keys, nums, flags);
      if(shmid < 0){
          perror("shmget");
          return -1;
      }
      return shmid;
  }
  
  int GreatShm(int nums){
    return Common(nums, IPC_CREAT|IPC_EXCL);
  }
  
  int GetShm(int nums){
    return Common( nums, IPC_CREAT);
  }
  
  int DestoryShm(int shmid){
      if(shmctl(shmid, IPC_RMID, NULL)<0){
          perror("shmctl");
          return -2;
      }
      return 0;
  }
serves.c
   #include"comm.h"
   #include<unistd.h>
   
   int main(){
       int shmid = GreatShm(4096);
       printf("shmid id:%d\n", shmid);
   
       char* addr = shmat(shmid, NULL, 0);
       *addr = '\0';
  
      int i=0;
      while(i<12){
      i++;
     printf("addr:%s\n", addr);
      sleep(1);
      }
      shmdt(addr);
      DestoryShm(shmid);
  
      return 0;
  }

client.c

 #include"comm.h"
   #include<string.h>
   
   int main(){
       int shmid = GetShm(4096);
       printf("shmid id:%d\n", shmid);
       char* addr = shmat(shmid, NULL, 0);
   
       int i=0;
      while(i<8){
          addr[i] = 'a';
          i++;
          printf("addr:%s\n", addr);
          sleep(1);
      }
  
      addr[i] = '\0';
  
      shmdt(addr);
  //  DestoryShm(shmid);
      return 0;
  }

Makefile

  .PHONY:all
   all:client serve
   
   client:client.c  ret.c
       gcc -o $@ $^
   serve:serves.c ret.c
       gcc -o $@ $^
   
   .PHONY:clean
  clean:
      rm -f serve client

运行结果

 

分享如上,望大家天天有进步!还有注各位看文的小朋友,节日快乐哈!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值