基于C/C++的共享内存的创建和使用(Linux)

文章详细介绍了如何使用C语言中的ftok、shmget、shmat、shmdt和shmctl函数来创建、映射、使用和管理共享内存,以及两个示例程序展示了共享内存的创建和操作过程。
摘要由CSDN通过智能技术生成

流程:

  1. 生成一个key值(函数:ftok)
  2. 创建共享内存,返回一个共享内存id(函数:shmget)
  3. 映射共享内存,关联的到当前进程,得到虚拟地址(函数:shmat)
  4. 使用内存,此时操作shmat函数返回的指针就是使用共享内存
  5. 解除映射(函数:shmdt)
  6. 销毁共享内存(函数:shmctl)
  7. 对于其他进程,在共享内存创建后,需要通过相同的 ‘key’ 值去获取并使用,使用完之后视情况决定是否销毁共享内存,因为你销毁了,其它进程也无法使用了。

代码:

// 11.c

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

typedef struct test
{
    char aa[100];
    int  bb;
}Test;


int main()
{
    // 生成一个key
    key_t key = ftok(".", 66);

    printf("11-key = %#x\n", key);

    //当只有IPC_CREAT选项打开时,不管是否已存在该块共享内存,则都返回该共享内存的ID,若不存在则创建共享内存
    //当只有IPC_EXCL选项打开时,不管有没有该快共享内存,shmget()都返回-1
    //所以当IPC_CREAT | IPC_EXCL时, 如果没有该块共享内存,则创建,并返回共享内存ID。若已有该块共享内存,则返回-1。

    // 创建共享内存,返回一个id
    int shmid = shmget(key, sizeof(Test), IPC_CREAT|0666); 
    if(-1 == shmid) 
    {
        perror("shmget failed");
        exit(1);
    }

    // 映射共享内存,得到虚拟地址
    Test *pTest = (Test *)shmat(shmid, 0, 0);
    if(NULL == pTest)
    {
        perror("shmat failed");
        exit(2);
    }

    while (1)
    {
        if(pTest != NULL)
        {
          printf("data int = %d\n", pTest->bb);
          sleep(2);
        }
    }
    
    // 解除映射
    if(-1 == shmdt(pTest))
    {
        perror("shmdt failed");
        exit(3);
    }
    
    printf("解除映射成功!\n");

    // 销毁共享内存
    if(-1 == shmctl(shmid, IPC_RMID, NULL))
    {
        perror("shmctl failed");
        exit(4);
    }

    return 0;
}

// 22.c

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

typedef struct test
{
    char aa[100];
    int  bb;
}Test;


int main()
{
    // 生成一个key
    key_t key = ftok(".", 66);
    printf("22-key = %#x\n", key);

    // 获取共享内存,返回一个id
    int shmid = shmget(key, 0, IPC_CREAT);
    if(-1 == shmid)
    {
        perror("shmget failed");
        exit(1);
    }

    // 映射共享内存,得到虚拟地址
     Test *pTest = ( Test *)shmat(shmid, NULL, 0);
    if(NULL == pTest)
    {
        perror("shmat failed");
        exit(2);
    }

    int num = 0;
    while (num < 10)
    {
       if (pTest != NULL)
       {
            sleep(3);
            pTest->bb = num;
            num++;
       }
    }
    
    // 解除映射
    if(-1 == shmdt(pTest))
    {
        perror("shmdt failed");
        exit(3);
    }
    printf("解除映射成功!\n");

/*
    // 销毁共享内存
    if(-1 == shmctl(shmid, IPC_RMID, NULL))
    {
        perror("shmctl failed");
        exit(4);
    }
*/

    printf("22 exit!! \n");

    return 0;
}

查看共享内存:

ubuntu@one:~/workspace/test$ ipcs

------------ 共享内存段 --------------
键        shmid      拥有者       权限        字节      连接数   状态      
0x00000000 34         ubuntu     600        524288     2          目标       
0x00000000 41         ubuntu     600        524288     2          目标       
0x00000000 43         ubuntu     600        524288     2          目标       
0x42081b50 44         ubuntu     666        104        2   

最下面一行就是我们创建的共享内存,其中的 ‘键’ = 0x42081b50 就是 创建共享内存时的 ‘key’ 值。

结束!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值