共享内存
最为高效的进程间通信方式 进程直接读写内存,不需要任何数据的拷贝 •为了在多个进程间交换信息,内核专门留出了一块内存区 •由需要访问的进程将其映射到自己私有地址空间 •进程直接读写这一内存区而不需要进行数据的拷贝,提高了效率 多个进程共享一段内存,需要依靠某种同步机制,如互斥锁和信号量等
l共享内存编程步骤: 1. 创建共享内存 •函数shmget() •从内存中获得一段共享内存区域 2. 映射共享内存 •把这段创建的共享内存映射到具体的进程空间中 •函数shmat() 3. 使用这段共享内存 •可以使用不带缓冲的I/O读写命令对其进行操作 4. 撤销映射操作: 函数shmdt() 5. 删除共享内存: 函数shctl()
下面给出几个实例说明上述函数的相关用法。
1.用shmget函数编制一个创建或打开一块新共享内存的函数
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int openshm(int size)
{
int shmid;
if(shmid=shmget(IPC_PRIVATE,size,0)==-1)
{
printf(" Get shared memory failed!\n");
return -1;
}
return shmid;
}
2.用共享内存实现客户--服务器的通信模式
2.1服务器程序
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
int main()
{
int shmid;
char c;
char *shmptr, *s;
if((shmid=shmget(1234,256,IPC_CREAT | 0666))<0)
{
printf("shmget failed.\n");
exit(1);
}
if((shmptr=shmat(shmid,0,0))==-1)
{
shmctl(shmid, IPC_RMID, (struct shmid_ds *)shmptr);
printf("shmat failed.\n");
exit(2);
}
s=shmptr;
for(c='a';c<='z';c++)
*s++=c;
*s=NULL;
while(*shmptr!='*')
sleep(1);
shmctl(shmid, IPC_RMID, (struct shmid_ds *)shmptr);
return 0;
}
2.2客户程序如下:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
int main()
{
int shmid;
char c;
char*shmptr, *s;
if((shmid=shmget(1234,256, 0666))<0)
{
printf("shmget failed.\n");
exit(1);
}
if((shmptr=shmat(shmid,0,0))==-1)
{
shmctl(shmid,IPC_RMID,(struct shmid_ds *)shmptr);
printf("shmat failed.\n");
exit(2);
}
for(s=shmptr;*s!=NULL;s++)
putchar(*s);
printf("\n");
*shmptr='*';
return 0;
}
3.当系统调用shmat中的addr取值为0时,共享内存附加到的地址是完全由系统决定的,这个程序测试共享内存附加到的地址
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
char array[4000];
int main()
{
int shmid;
char *ptr, *shmptr;
printf("array[] form %x to %x \n",&array[0],&array[3999]);
printf("stack around %x \n", &shmid);
if((ptr=malloc(10000))==NULL)
{
printf("malloc failed.\n");
exit(1);
}
if((shmid=shmget(IPC_PRIVATE,10000,SHM_R|SHM_W))<0)
{
printf("shmget failed.\n");
exit(2);
}
if((shmptr=shmat(shmid,0,0))==-1)
{
printf("shmat failed.\n");
exit(3);
}
printf("shared memory attached from %x to %x \n",shmptr,shmptr-10000);
if(shmctl(shmid,IPC_RMID,0)<0)
{
printf("shmctl failed.\n");
exit(4);
}
return 0;
}