Linux C编程--进程间通信(IPC)5--System V IPC 机制3--共享内存

时间:2022-05-12 14:55:04

共享内存

最为高效的进程间通信方式   进程直接读写内存,不需要任何数据的拷贝  •为了在多个进程间交换信息,内核专门留出了一块内存区  •由需要访问的进程将其映射到自己私有地址空间  •进程直接读写这一内存区而不需要进行数据的拷贝,提高了效率 多个进程共享一段内存,需要依靠某种同步机制,如互斥锁和信号量等

Linux C编程--进程间通信(IPC)5--System V IPC 机制3--共享内存

 

l共享内存编程步骤:  1. 创建共享内存    •函数shmget()    •从内存中获得一段共享内存区域   2. 映射共享内存    •把这段创建的共享内存映射到具体的进程空间中    •函数shmat()   3. 使用这段共享内存    •可以使用不带缓冲的I/O读写命令对其进行操作   4. 撤销映射操作: 函数shmdt()   5. 删除共享内存: 函数shctl() 

Linux C编程--进程间通信(IPC)5--System V IPC 机制3--共享内存

Linux C编程--进程间通信(IPC)5--System V IPC 机制3--共享内存

Linux C编程--进程间通信(IPC)5--System V IPC 机制3--共享内存

Linux C编程--进程间通信(IPC)5--System V IPC 机制3--共享内存

Linux C编程--进程间通信(IPC)5--System V IPC 机制3--共享内存

 下面给出几个实例说明上述函数的相关用法。

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;
}