共享内存是进程间通信的最快方式。
每个运行的进程都有自己的虚拟内存;共享内存是在物理内存中开辟一个空间,允许多个进程把它映射进各自的虚拟内存空间,所以可用来多个进程间进行通信;缺点是没有同步机制,所以都是和信号量配合使用。所以说共享内存涉及到两个内存概念,一个是物理内存中的一片区域,一个是各个进程中的虚拟内存;进程对各自虚拟内存的操作就相当于是对物理内存的操作;
进程间通信查看的shell命令是ipcs,可以查看到系统的共享内存、信号量和消息队列;#ipcs -m是只查看共享内存;
对共享内存的操作流程分为以下几个步骤:
1、在内核空间分配一块内核空间,可以得到此空间的id;
2、把此空间映射到我们的用户空间,得到一个空间地址;
3、对此用户空间进行操作;
4、关闭映射;
5、删除共享内存;
第一步,得到一块内核空间的函数:int shmget(key_t key,size_t size,int shmflag);成功返回shmid,失败返回-1;
key一般是一个路径,用ftok转换为一个key值,所有的ipc对象都需要一个key值,key值可以理解为这个ipc对象的实际标识;函数的返回值也是一个int的标识,程序通过这个标识来操作ipc,这样就实现了与真实ipc的隔离;
size是要开辟的共享内存的大小;
flag:IPC_CREAT创建共享内存;IPC_EXCL,共享内存存在时报错;另外还有权限,如0666,与文件操作一下;
第二步:映射void shmat(int shmid,void *shmaddr,int shmflag);成功返回地址,失败返回(void )-1;
第三步:操作,memcpy,即拷贝字符串到shmat,当然也可以定义数据结构等其他格式;
第四步,分离 shmdt(const void*shmaddr),非删除,只是把共享内存从此程序中分离出来;0成功 -1失败
第五步。int shmctl(int shmid,int cmd,struct chmid_ds *buf);
cmd是对shmid操作的命令,可以是删除、或其他操作,比如改变共享内存大小,此时第三个参数buf排上用场;
———————————————————
实例:进程间通信,一个读,一个写 使用share mem
write.c
#include <>
void shmaddr=(void )0;
char info[]=”hello world”;
int main()
{
int shmid=shmget(12345,2048,IPC_CREAT);
if(shmid!=-1)
{
shmaddr=shmat(shmid,0,0);
if(shmaddr != (void *)-1)
{
memcpy(ahmaddr,info,12);
printf(“copy success\n”);
shmdt(shmaddr);
}else
perror(“shmat:”)
}
perror(“shmget:”)
return 0 ;
}
读和写基本一样,
read.c
include <>
void *shmaddr=(void *)0;
int main()
{
int shmid=shmget(12345,2048,IPC_CREAT);
if(shmid!=-1)
{
shmaddr=shmat(shmid,0,0);
if(shmaddr != (void *)-1)
{
**printf("the share mem is:%s\n",shmaddr);**
shmdt(shmaddr);
**shmctl(shmid,IPC_RMID,0)**;//此处删除
}else
perror("shmat:")
}
perror("shmget:")
return 0 ;
}
注意 共享内存不会自己删除,需要程序员手动删除