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

时间:2022-05-12 14:54:58

共享内存

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

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