本文主要探讨unix/linux间的一种通信方式———共享内存
共享内存简介
共享内存指在多处理器的计算机系统中,可以被不同CPU访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对进行缓存。任何一个缓存的数据被更新后,由于其他处理器也可能要存取,共享内存就需要立即更新,否则不同的处理器可能用到不同的数据。共享内存是 unix下的多进程之间的通信方法 ,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。
共享内存相关函数
共享内存创建
int shmget(key_t key, size_t size, int shmflg);
参数:
key:键值
size:共享内存大小
shmflg:
0:取共享内存标识符,若不存在则函数会报错。
IPC_CREAT:当shmflg&IPC_CREAT为真时,如果内核中不存在键值与
key相等的共享内存,则新建一个共享内存。如果存在这样的共享内存,返
回此共享内存的标识符。
IPC_CREAT|IPC_EXCL:如果内核中不存在键值 与key相等的共享内存,
则新建一个共享内存,如果存在这样的共享内存则报错。
返回值:
成功执行返回共享内存标识符,失败返回-1。
共享内存挂载
void *shmat(int shmid, const void *shmaddr, int shmflg);
参数:
shimid:共享内存标识符
shmaddr:共享内存挂载点
0:存储段连接到由内核选择的第一个可以地址上
NULL:系统将自动选择一个合适的地址
其他指定地址
shmflg:
SHM_RDONLY:共享内存只读
0:表示共享内存可读写
返回值:
成功执行返回共享内存挂载点地址,失败返回-1。
共享内存管理
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数:
shmid:共享内存标识符
cmd:
IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构复制到
buf中
IPC_SET:改变共享内存的状态,把buf所指的shmid_ds结构中的uid、
gid、mode复制到共享内存的shmid_ds结构内
IPC_RMID:删除这片共享内存
struct shmid_ds{
struct ipc_perm shm_perm;/*所有权和权限*/
size_t shm_segsz;/*段大小(字节)*/
time_t shm_time;/*上次连接时间*/
time_t shm_dtime;/*上次分离时间*/
time_t shm_time;/*上次更改时间*/
pid_t shm_cpid;/*创建者PID*/
pid_t shm_lpid;/*最后一个shmat的PID*/
shmatt_t shm_natch;/*当前附件数量*/
};
struct ipc_perm{
key_t __key;/*提供给shmget的密钥*/
uid_t uid;/*所有者的有效UID*/
gid_t gid;/*所有者的有效GID*/
uid_t提示;/*创建者的有效UID*/
gid_t cgid;/*创建者的有效GID*/
unsigned short;/*权限+SHM_DEST和
SHM_LOCKED标志*/
unsigned short__seq;/*序列号*/
};
共享内存删除
int shmdt(const void *shmaddr);
参数:
shmaddr:共享内存挂载点
返回值:
执行成功返回0,失败返回-1。
demo:
1.创建共享内存,写入hello word
2.创建程序读取共享内存
3.删除共享内存及其内容
shm_send.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void result()
{
key_t key;
char *shmaddr = NULL;
char *buf = "hello word";
key = ftok(".",128);
if(key == -1)
{
printf("create key fail\n");
perror("why:");
exit(-1);
}
int shm_id = shmget(key,1024,IPC_CREAT|0777);
if(shm_id == -1)
{
printf("create show memmory fail\n");
perror("why:");
exit(-1);
}
shmaddr = shmat(shm_id,0,0);
if(shmaddr == NULL)
{
printf("memmory map fail\n");
perror("why:");
exit(-1);
}
strcpy(shmaddr,buf);
sleep(5);
int shm_con = shmctl(shm_id,IPC_RMID,NULL);
if(shm_con == -1)
{
printf("delete data fail\n");
perror("why:");
exit(-1);
}
int shm_del = shmdt(shmaddr);
if(shm_del == -1)
{
printf("deltel show memmory fail \n ");
perror("why");
exit(-1);
}
}
int main()
{
result();
return 0;
}
shm_get.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void result()
{
key_t key;
char *shm_addr = NULL;
key = ftok(".",128);
if(key == -1)
{
printf("key create fail\n");
perror("why");
exit(-1);
}
int shm_id = shmget(key,1024,IPC_CREAT|0777);
if(shm_id == -1)
{
printf("create show memory fail\n");
perror("why:");
exit(-1);
}
shm_addr = shmat(shm_id,0,0);
if(shm_addr == NULL)
{
printf("show momory map fail\n");
perror("why:");
exit(-1);
}
printf("show memory : %s\n",shm_addr);
int shm_con = shmctl(shm_id,IPC_RMID,NULL);
if(shm_con == -1)
{
printf("detel data fail\n");
perror("why:");
exit(-1);
}
}
int main()
{
result();
return 0;
}
结果示例: