基于C/C++的共享内存的创建和使用(Linux)
流程:
- 生成一个key值(函数:ftok)
- 创建共享内存,返回一个共享内存id(函数:shmget)
- 映射共享内存,关联的到当前进程,得到虚拟地址(函数:shmat)
- 使用内存,此时操作shmat函数返回的指针就是使用共享内存
- 解除映射(函数:shmdt)
- 销毁共享内存(函数:shmctl)
- 对于其他进程,在共享内存创建后,需要通过相同的 ‘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’ 值。
结束!