重温Linux中的共享内存通信方式

一直在为找大三的实习做准备,很长一段时间都没有更新我的CSDN了,期间主要就是画思维导图来实现构建知识体系,思维导图的链接:https://gitee.com/lemaliu/my_computer_knowledge_system,现在终于有时间安心静下来好好沉淀沉淀了。

经过这段时间的面试,发现共享内存被问的频率虽然不高,但一直对它没有一个深刻的理解,认为就是Linux下进程间通信的一种方式,仅仅写过简单的代码(进程通信,一问一答等),现在对共享内存进行一个比较深入的学习,接下来从以下几个方面来重新探寻一下共享内存。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

目录

什么是共享内存

为什么共享内存是最快的进程间通信方式

共享内存的基本使用方法简单演示


 

什么是共享内存为什么共享内存是最快的进程间通信方式

什么是共享内存?

在wiki百科中,共享内存分为硬件层面和软件层面的理解,这篇博客仅探究共享内存的软件层面。

进程间通信的方式中,共享内存的速度是最快的,因为管道,消息队列等在进行进程间通信的时候需要进行多次的用户空间到内核空间的切换,而共享内存不需要将数据频繁地在用户态和内核态进行拷贝。

下图为管道,消息队列的数据传递示意图

看到管道,消息队列等进行进程间通信的时候,需要不停在用户态和内核太之间进行数据的复制和状态的切换,下图来看看共享内存的数据流向图

可以看到,共享内存在传输数据的时候,都是在用户态进行的,当两个进行映射到同一块共享地址空间的时候,往共享内存中写入,读取都是用户态的操作了,也就节约了大量的时间。

 

         共享内存的基本使用方法简单演示

使用Linux的系统调用接口,实现一个wshm.c向共享内存中写数据,然后实现一个rshm.c向共享内存中将其写入的数据读出来。

代码链接:https://gitee.com/lemaliu/blog_material_codes/tree/master/IPC/shared_memory/simple

具体代码:

/*
 *  file-name: wshm.c
 *  
 *  date: 2019-4-5
 *
 *  desc: IPC shared memory
 *
 */


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

int main()
{
  //create IPC key
  key_t key = ftok("./", 66);
  int* pp = NULL;
  void* addr = NULL;

  //create shared memory, return an ID
  int shmid = shmget(key, 100, IPC_CREAT|IPC_EXCL|0666);
  if(shmid == -1)
  {
    perror("shmget");
    return 1;
  }

  //detach the shared memory
  addr = shmat(shmid, 0, 0);
  if((void *)-1 == addr)
  {
    perror("shmat");
    return 1;
  }

  //write to shared memory
  pp = (int*)addr;
  *pp = 0x12312312;
  *(pp + 1) = 0x6fffffff;

  //destory detach
  if(-1 == shmdt(addr))
  {
    perror("shmdt");
    return 1;
  }
  printf("shmdt is successful\n");
  getchar();

  //delete shared memory
  if(-1 == shmctl(shmid, IPC_RMID, NULL))
  {
    perror("shmctl");
    return 1;
  }

  return 0;
}
/*
 *  file-name: rshm.c
 *  
 *  date: 2019-4-5
 *
 *  desc: IPC shared memory
 *
 */


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

int main()
{
  //create IPC key
  key_t key = ftok("./", 66);
  int* pp = NULL;
  void* addr = NULL;

  //create shared memory, return an ID
  int shmid = shmget(key, 0, 0);
  if(shmid == -1)
  {
    perror("shmget");
    return 1;
  }

  //detach the shared memory
  addr = shmat(shmid, 0, 0);
  if((void *)-1 == addr)
  {
    perror("shmat");
    return 1;
  }

  //read to shared memory
  pp = (int*)addr; 
  int x = *(int*)pp; 
  int y = *((int*)pp + 1);

  printf("read from shared memroy : 0x%x, 0x%x\n", x, y);

  //destory detach
  if(-1 == shmdt(addr))
  {
    perror("shmdt");
    return 1;
  }
  printf("shmdt is successful\n");
  getchar();

  //delete shared memory
  if(-1 == shmctl(shmid, IPC_RMID, NULL))
  {
    perror("shmctl");
    return 1;
  }

  return 0;
}

上述代码运行起来,会在rshm从共享内存读到数据。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值