Linux共享内存-进程间通信

linux中进程间通信的方法有不少,一般的进程间通信是通过linux内核来完成的,每次信息的交流都先传递给内核,由内核在转给另外一个进程。因此在执行过程中,不断的由用户态到内核态,再由内核态到用户态,消耗的资源非常大。

因此共享内存的出现大大的解决了这个问题,共享内存的实现仅仅在开始从内核中申请一段内存,借助这块内存,之后全部都是在用户态下完成的,由于不再由资源转换方面的浪费,使得进程间通信的速率得到的很大的提高。

可是说共享内存是最快的进程间通信方法。


共享内存

本质

申请了一块物理内存分别映射到N个进程虚拟地址空间,是几种进程间通信方式中性能最好的

特性

  • 能够应用于任意进程之间
  • 双向通行,每一个进程即可以读,也可以写
  • 没有面向字节流或者面向数据块的概念,随机访问内存中的数据
  • 没有内置同步互斥
  • 声明周期属于内核

API

  • 创建 shmget
int shmget(key_t key, size_t size, int shmflg);

key是申请共享内存的关键字;size表示想要申请多大的内存,默认是按照4k进行分配的,如果是打开的话一般填0即可;shmflg表示方法,创建使用IPC_CREAT | 0644,打开使用0

  • 挂接 shmat
void *shmat(int shmid, const void *shmaddr, int shmflg);

使用起来类似于malloc,参数shmif表示已经打开的共享内存,shmaddr表示你要挂载的地方,一般填NULL表示有系统自动分配,shmflg目前没有什么作用,填0即可。返回值为挂在区域的首地址。

  • 卸载
int shmdt(const void *shmaddr);

直接将调用shmat后所得到的挂载区域首地址(即返回值)作为参数即可。

shmdt使用起来类似free,进程结束系统系统会自动的进行shmdt

  • 销毁 shectl
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

参数shmid为打开的共享内存id,cmd为操作码,删除的话填入IPC_RMID,最后一个参数填0即可,暂时不关注。


演示代码

共有4部分:创建共享内存create,销毁共享内存destroy,读共享内存read,写共享内存。

shmcreate.c

#include <stdio.h>                                                                                                                                                         
#include <stdlib.h>                                                                                                                                                        
#include <sys/shm.h>                                                                                                                                                       
#include <sys/ipc.h>                                                                                                                                                       

int main()                                                                                                                                                                 
{                                                                                                                                                                          
  int shmid = shmget(1234, 100, IPC_CREAT|0644);                                                                                                                           
  if(shmid < 0 ){                                                                                                                                                          
    perror("shmget");                                                                                                                                                      
    return 1;                                                                                                                                                              
  }                                                                                                                                                                        

  printf("shared memory is create success...\n\n");                                                                                                                        
  return 0;                                                                                                                                                                
}     

shmdestroy.c

#include <stdio.h>                                                                                                                                                         
#include <stdlib.h>                                                                                                                                                        
#include <sys/ipc.h>                                                                                                                                                       
#include <sys/shm.h>                                                                                                                                                       

int main()                                                                                                                                                                 
{                                                                                                                                                                          
  int shmid = shmget(1234, 0, 0);                                                                                                                                          
  if(shmid < 0 ){                                                                                                                                                          
    perror("shmget");                                                                                                                                                      
    return 1;                                                                                                                                                              
  }                                                                                                                                                                        

  shmctl(shmid, IPC_RMID, 0);                                                                                                                                              
  return 0;                                                                                                                                                                
}     

read.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <sys/shm.h>
#include <sys/ipc.h>

int main(){
  //1.打开共享内存
  int shmid = shmget(1234, 0, 0);
  if(shmid < 0){
    perror("shmget open");
    return 1;
  }

  //2.挂载共享内存
  char *shm = (char *)shmat(shmid, NULL, 0);

  if(shm == NULL) {
    perror("shmat");
    return 1;
  }


  //3.读写数据
  char buf[1024];
  memset(buf, sizeof(buf), 0);
  int flag = 1;
  while(flag){
    printf("[1] continue   [0] exit:");
    scanf("%d",&flag);
    if(flag == 0)
      break;
    strcpy(buf, shm); 
    printf("read: [%s]\n",buf);
  }


  //4.卸载共享内存
  shmdt(shm);

  return 0;
}

write.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <sys/ipc.h>
#include <sys/shm.h>
int main()
{
  int shmid = shmget(1234, 0, 0);
  if(shmid < 0 ){
    perror("shared memory oper");
    return 1;
  }

  char* shmaddr =(char *) shmat(shmid, NULL, 0);
  if(shmaddr == NULL){
    perror("shmat");
    return 1;
  }

  char buf[1024];
  memset(buf, sizeof(buf), 0); 

  strcpy(shmaddr, "1234");

  while(1)
  {
    printf("write[ exit:1 ]: ");
    scanf("%s",buf);
    printf("[buf]:%s\n",buf);
    if( strcmp(buf,"1")==0 )
      break;
    strcpy(shmaddr, buf);
    printf("write succrss!\n");
  }


  shmdt(shmaddr);
  return 0;
}

猜你喜欢

转载自blog.csdn.net/xiaozuo666/article/details/80648678