Linux系统编程————进程间通信--共享内存

共享内存又称内存映射

什么是共享内存

        共享内存就是多个进程将一块物理内存分别映射到自己的虚拟空间地址上,最终实现多个进程共享同一块物理内存。

创建共享内存/内存映射区:

        mmap———创建内存映射

        作用:将磁盘文件映射到内存,用户通过修改内存就能修改磁盘文件,mmap既可以单纯的操作文件,也可以进行进程间通信。

        函数原型:void* mmap ( void * addr , size_t len , int prot , int flags , int fd , off_t offset ) 

        参数:
             addr是映射区首地址,传NULL;
             len是映射到调用进程地址空间的字节数;
             prot 参数指定共享内存的访问权限;
             flags是标志位参数,由以下几个常值指定:MAP_SHARED , MAP_PRIVATE , MAP_FIXED,其中,MAP_SHARED , MAP_PRIVATE必选其一;
             fd是打开的文件描述符,若没有文件则为-1;
             offset参数一般设为0,表示从文件头开始映射。

mmap在有无血缘关系的进程间使用是不同的

        没有血缘关系的进程通过共享内存通信:
               1、不能使用匿名的映射方式;
               2、只能借助磁盘文件创建映射区;
        磁盘文件只是中间桥梁,让两个进程的映射区指向同一块物理内存,操作的数据都在内存上

        

使用mmap函数进行进程间通信

例1、使用共享内存在父子进程间通信

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<sys/wait.h>

int main()
{
	int len = 4096;//必须是4096的整数倍
	//创建匿名共享内存
	void* ptr =  mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANON,-1,0);
	if(ptr == MAP_FAILED)
	{
		perror("mmap error");
		exit(-1);
	}
	
	//创建子进程
	pid_t pid = fork();
	if(pid < 0)
	{
		perror("fork error");
		exit(-1);
	}
	//父进程在共享内存中写数据
	if(pid > 0)
	{
		strcpy((char*)ptr,"这是匿名的共享内存!\n");
		wait(NULL);//进程回收
	}
	//子进程读
	if(pid == 0)
	{
		printf("%s\n",(char*)ptr);
	}

	//释放共享内存
	int ret = munmap(ptr,len);
	if(ret == -1)
	{
		perror("munmap error\n");
		exit(-1);
	}

	return 0;
}

例2、使用共享内存在无血缘关系的进程间通信

A进程:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<sys/wait.h>

int main()
{
	int fd = open("temp",O_RDWR | O_CREAT,0664);
	ftruncate(fd,4096);//给磁盘文件扩展空间
	int len = lseek(fd,0,SEEK_END);//求文件大小

	//创建有名共享内存
	void* ptr =  mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);
	if(ptr == MAP_FAILED)
	{
		perror("mmap error");
		exit(-1);
	}
	while(1)
	{
		strcpy((char*)ptr,"这是无血缘关系进程间的共享内存!\n");
		sleep(2);
	}

	//释放共享内存
	int ret = munmap(ptr,len);
	if(ret == -1)
	{
		perror("munmap error\n");
		exit(-1);
	}

	return 0;
}

B进程:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<sys/wait.h>

int main()
{
	int fd = open("temp",O_RDWR | O_CREAT,0664);
	ftruncate(fd,4096);//给磁盘文件扩展空间
        int len = lseek(fd,0,SEEK_END);//求文件大小
	
	void* ptr =  mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);
	if(ptr == MAP_FAILED)
	{
		perror("mmap error");
		exit(-1);
	}
	
	while(1)
	{
		sleep(1);
		printf("%s\n",(char*)ptr);
	}

	//释放共享内存
	int ret = munmap(ptr,len);
	if(ret == -1)
	{
		perror("munmap error\n");
		exit(-1);
	}

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值