1、验证共享映射后修改文件内容,是否能够同步
先创建一个映射文件,写入数据
分为四个步骤
1、打开映射文件
设文件描述符,使用open函数
int fd;
if((fd=open("mapfile",O_RDWR))==-1)
{ perror("open failed");exit(0);
}
获取文件大小,作为映射大小
int fsize;
fsize=lseek(fd,0,SEEK_END);
2、进行共享映射
int * ptr=NULL;
if((ptr=mmap(NULL,fsize,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0))==MAP_FAILED)
{perror("mmap failed");exit(0);
}
3、映射成功,关闭描述符
close(fd);
4、修改映射内存
munmap释放映射的函数
ptr[0]=0x34333231;
munmap(ptr,fsize);
完整代码
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/fcntl.h>
#include<sys/mman.h>int main()
{int fd; if((fd=open("mapfile",O_RDWR))==-1){ perror("open failed");exit(0);} int fsize;fsize=lseek(fd,0,SEEK_END);int * ptr=NULL;if((ptr=mmap(NULL,fsize,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0))==MAP_FAILED){perror("mmap failed");exit(0);}close(fd);ptr[0]=0x34333231;munmap(ptr,fsize);return 0;
}
成功截图
2、验证两个进程是否能够建立共享通信的方式
前提:必须保证映射文件是空的(保证不会出现还没有开始通信,但读端以及读到了数据的情况),但是需要有大小(否则无法映射)
使用ftruncate函数阶段,可以将文件大小变小或拓展空文件
写端
1、按照给对方的需求,定义一个结构体
typedef struct
{int id;char name[1024];}shared_t;
2、创建文件
int fd=open("MAPIC",O_RDWR|O_CREAT,0664);
3、将文件截断
ftruncate(fd,sizeof(shared_t));
4、使用结构体指针进行映射
shared_t* ptr;
ptr=mmap(NULL,sizeof(shared_t),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
5、将结构体里的数据初始化
ptr->id=0;
bzero(ptr->name,1024);
6、循环写入数据
while(1)
{++ptr->id;sprintf(ptr->name,"test message id %d",ptr->id);sleep(1);
}
7、 释放映射,关闭文件描述符
munmap(ptr,sizeof(shared_t));
close(fd);
总代码
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/fcntl.h>
#include<sys/mman.h>
#include<sys/types.h>typedef struct
{int id;char name[1024];}shared_t;int main()
{int fd=open("MAPIC",O_RDWR|O_CREAT,0664);ftruncate(fd,sizeof(shared_t));shared_t* ptr;ptr=mmap(NULL,sizeof(shared_t),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);ptr->id=0;bzero(ptr->name,1024);while(1){++ptr->id;sprintf(ptr->name,"test message id %d",ptr->id);sleep(1);}munmap(ptr,sizeof(shared_t));close(fd);return 0;
}
读端
读端只需要读即可
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/fcntl.h>
#include<sys/mman.h>
#include<sys/types.h>typedef struct
{int id; char name[1024];
}shared_t;int main()
{int fd=open("MAPIC",O_RDWR,0664);shared_t* ptr;ptr=mmap(NULL,sizeof(shared_t),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);while(1){ printf("%s\n",ptr->name);sleep(1);}munmap(ptr,sizeof(shared_t));close(fd);return 0;
}
3、mmap使用时容易出现的错误
如果其他对某文件没有权限的人也通过映射的方式将文件修改了,则意味着无论是否有权限,任何人都能修改任何文件,为了避免此类现象,有两种措施
1、每次映射前先出进程查看用户权限,然后再决定映射方式,但这种方式效率低
2、mmap映射时,映射的权限要小于等于open的权限,因为如果用户对文件只有读权限,就无法读写打开