您的位置:首页 > 运维架构 > Linux

Linux系统编程:mmap介绍和使用mmap实现进程间通信

2018-03-23 00:24 375 查看

mmap函数介绍

这个函数有啥子作用?m-> memory 内存,map ->映射,见名知义,就是创建内存映射区,作用就是:将磁盘文件的数据映射到内存,用户通过修改内存就能修改磁盘文件。所以我们可以用mmap来修改文件,也可以用于进程间通信

函数原型

void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);看上去参数比较多,我们理解了也就没啥子了。
void *addr:映射区的首地址,你知道么?肯定不知道创建了才有,传NULL

size_t length:映射区的大小,可以传文件大小,也可以自己自己指定,单位是byte。不能为0。

int prot:映射区权限,可以为:PROT_READ 映射区必须要有读权限,PROT_WRITE,PROT_READ|PROT_WRITE
 int flags:标志位参数,可以为MAP_SHARED 修改内存数据会同步到磁盘。MAP_PRIVATE 修改了内存数据不会同步到磁盘
int fd:文件描述符,要映射的文件对应的id。通过open函数得到
off_t offset:映射文件的偏移量,要么为0 要么为4k的整数倍.

munmap函数

创建了内存映射区,当然也要对应的释放内存映射区的操作,这里就用的munmap了。比较简单,直接看函数原型:
int munmap(void *addr, size_t length);

addr 为映射区地址就是 mmap返回值,length 就是 mmap 中你指定的长度。

使用mmap实现进程间通信

我们用mmap来实现 2个 进程间的通信,一个进程写数据,另一个进程读数据。我们这里让write 进程每次sleep 1s,read进程每次sleep 2s,这样更能看见效果。

mmap_file_write.c

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

int main(void)
{
int fd = open("temp",O_RDWR|O_CREAT,0664);
if(fd==-1)
{
perror("open hello");
exit(1);
}
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);
}
char* temp = (char*)ptr;
int i = 1;
while(1)
{
//对映射区进行写操作
char str[1024]={0};
sprintf(str,"This is line %d",i);
strcpy(temp,str);
//temp[0] = 'a';
printf("写入数据:%s\n",temp);
temp += strlen(str);
sleep(1);
i++;
}
//释放内存映射区
int ret = munmap(ptr,len);
if(ret==-1)
{
perror("munmap");
exit(1);
}
close(fd);
return 0;
}

mmap_file_read.c

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

int main(void)
{
int fd = open("temp",O_RDWR|O_CREAT,0664);
if(fd==-1)
{
perror("open hello");
exit(1);
}
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);
}
char* temp = (char*)ptr;
while(1)
{
//对映射区进想读操作
char str[1024] = {0};
strcpy(str,temp);
printf("%s\n",str);
temp+=strlen(str);
sleep(2);
}
int ret = munmap(ptr,len);
if(ret==-1)
{
perror("munmap");
exit(1);
}
close(fd);
return 0;
}

进程间通信效果



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: