共享内存是通过将内核分配的共享存储区映射到进程的地址空间实现的,没有数据复制过程。在以前的博客关于操作系统的那部分写到过。
使用共享内存应该先创建共享内存,有道理,不创建哪来内存啊。由shmget创建,shmat将共享内存映射到调用进程的地址空间,映射完成后,通过返回共享内存读写指针对共享
内存进行读写,调用shmdt关闭共享内存映射。
下面是一个案例,对比队列整体上是差不多的。新建了一个共享内存,调用msgctl设置其访问权限为对非属主用户和非属主用户组的其他用户组只读,最后删除共享内存。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
typedef struct
{
int n;
char str[256];
} ShmStru;//用来映射共享内存的结构
int main()
{
key_t lKey;
int nShmId;//内存标识符变量
struct shmid_ds sds;
if((lKey = ftok("/etc/profile",3)) == -1)//生成键值
{
perror("ftok");
exit(1);
}
if((nShmId = shmget(lKey,sizeof(ShmStru),IPC_CREAT|0666)) == -1)//创建共享内存
{
perror("shmget");
exit(2);
}
memset(&sds,0x00,sizeof(struct shmid_ds));//清空结构体
if(shmctl(nShmId,IPC_STAT,&sds) < 0)//获取共享内存的属性
{
perror("shmctl IPC_STAT");
exit(3);
}
printf("First shm_perm.mode=0%o\n",sds.shm_perm.mode);//输出共享内存的访问权限
sds.shm_perm.mode &= (~0002);//去除其他用户的写权限
if(shmctl(nShmId,IPC_SET,&sds) < 0)//设置共享内存权限
{
perror("shmctl IPC_SET");
exit(4);
}
memset(&sds,0x00,sizeof(struct shmid_ds));//清空结构体
if(shmctl(nShmId,IPC_STAT,&sds) < 0)//清空变量
{
perror("shmctl IPC_STAT");
exit(5);
}
printf("Second shm_perm.mode=0%o\n",sds.shm_perm.mode);//第二次改变
if(shmctl(nShmId,IPC_RMID,NULL) < 0)//删除共享内存
{
perror("shmctl IPC_RMID");
exit(6);
}
return 0;
}