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

流程:

  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 = %#xn", 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 = %dn", 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 = %#xn", 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’ 值。

结束!