Linux关于进程间通信共享内存

共享内存概念

共享内存允许两个不相关的进程去访问同一部分逻辑内存 如果需要在两个运行中的进程之间传输数据,共享内存将是一种效率极高的解决方案

共享内存是由IPC为一个进程创建的一个特殊的地址范围,它将出现在进程的地址空间中。 其他进程可以把同一段共享内存段“连接到”它们自己的地址空间里去。 所有进程都可以访问共享内存地址,就好像它们是有malloc分配的一样 如果一个进程向这段共享内存写了数据,所做的改动会立刻被有权访问同一段共享内存的其他进程看到

关于共享内存的操作

以下代码创建一块共享内存

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

int main()
{
    int shmid = shmid = shmget((key_t)1234,2048,IPC_CREAT|0766);
    printf("shmid = %d\n",shmid);
   
    return 0;
}

但实际我们要这样创建,先删除之前可能存在的内存,在创建一块自己的内存

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

int main()
{
    int shmid = shmget((key_t)1234,0,0);
    if(shmid > 0)
    {
        shmctl(shmid,IPC_RMID,0);
        shmid = shmget((key_t)1234,2048,IPC_CREAT|0766);
        printf("shmid = %d\n",shmid);
    }
    return 0;
}

下面演示为什么要这样做

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

int main()
{
 //   int shmid = shmget((key_t)1234,2048,IPC_CREAT|0766);
    int shmid = shmget((key_t)1234,0,0);
    if(shmid > 0)
    {
        shmctl(shmid,IPC_RMID,0);        
    }

   shmid = shmget((key_t)1234,2048,IPC_CREAT|0766);
    void *ptr = shmat(shmid,NULL,0);
    memcpy(ptr,"helloworld",strlen("helloworld"));
    printf("shmid = %d\n",shmid);
    return 0;
}

先注释掉第一段代码是最开始实现的开辟共享内存,剩下的是第二种方法实现开辟共享内存,我们运行程序,不会出错

当我们把第一段代码释放掉,下面实现的第二种方法注释起来

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

int main()
{
    int shmid = shmget((key_t)1234,4096,IPC_CREAT|0766);
    //int shmid = shmget((key_t)1234,0,0);
    //if(shmid > 0)
    //{
    //    shmctl(shmid,IPC_RMID,0);
    //}  

    //    shmid = shmget((key_t)1234,2048,IPC_CREAT|0766);
    void *ptr = shmat(shmid,NULL,0);
    memcpy(ptr,"helloworld",strlen("helloworld"));
    printf("shmid = %d\n",shmid);
    return 0;
}

出现以下结果:

我们来分析一下,仔细看红色的那一段代码,我们把开辟的内存开辟成4096,当我们之前的内存没有清掉,此时我们使用共享内存是一样的,但是开辟出来更大的空间,此时使用shmat映射逻辑地址就会出现段错误。

所以当我们进行服务器开发的时候,如果同组成员之前开辟了共享内存ID为1234,而我们后面也开辟了ID为1234的共享内存,但是我们不知道他开辟了多大,如果一旦开辟不一样大,进行映射逻辑地址的时候就会出错。避免这样的事情发生,我们在开辟共享内存之前,对共享内存进行删除,再进行创建,就会避免这样的事情发生。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值