mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。
具体函数定义如下:
#include <sys/mman.h>
/*映射函数*/
/*映射函数*/
int munmap(void *start,
size_t length);
网上找寻了多个例子运行,经常会发生段错误或是总线错误,通过GDB调试发现大多是由于分配的指针地址问题,例如无地址等,特此记录。
小例子:
*********************Process A******************************
#include <stdio.h>
#include <sys/mman.h> /* for mmap and munmap */
#include <sys/types.h> /* for open */
#include <sys/stat.h> /* for open */
#include <fcntl.h> /* for open */
#include <unistd.h> /* for lseek and write */
int main()
{
int fd,ret;
char *prt;
char *msg="I am Process A!\n";
/*记得加上 O_CREAT,没有该文件会自动创建,否则会报错*/
fd=open("/tmp/sharefile",O_RDWR|O_CREAT,00777);
if(fd==-1){
perror("open error!\n");
return 0;
}
/*truncate函数
ret=truncate("/tmp/sharefile",4096);
prt=(char*) mmap(NULL,strlen(msg)+1,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(*prt == -1)
{
perror("mmap error!\n");
}
close(fd);
/*此时的memcpy就相当于利用write在写文件一样*/
memcpy(prt,msg,strlen(msg)+1);
printf("%s",prt);
sleep(10);
printf("%s",prt);
/*用完记得解除映射,资源利用完最好都回收做个环保的好孩子*/
munmap(prt,strlen(msg)+1);
return 0;
}
***************************Process B***********************************
#include <sys/mman.h> /* for mmap and munmap */
#include <sys/types.h> /* for open */
#include <sys/stat.h> /* for open */
#include <fcntl.h> /* for open */
#include <unistd.h> /* for lseek and write */
#include <stdio.h>
int main()
{
int fd,ret;
char *prt;
char *msg=" I am Process B!";
fd=open("/tmp/sharefile",O_RDWR|O_CREAT,00777);
if(fd==-1){
perror("open error!\n");
return 0;
}
/*查询文件状态如果文件存在可用就用不着创建了,这里定义mmap_file时候如果像文中是指针的一定要先分配地址,不然会有总线错误,或是直接别指针了,struct stat mmap_file就行,然后传进stat()时给地址&mmap_file,当然后面的if里内容也要变成mmap_file.st_size*/
struct stat *mmap_file;
mmap_file=(struct stat*)malloc(sizeof(struct stat));
ret=stat("/tmp/sharefile",mmap_file);
if(ret==-1){
perror("error!\n");
return 0;
}
if(mmap_file->st_size==0){
ret=truncate("/tmp/sharefile",4096);
}
prt=(char*) mmap(NULL,strlen(msg)+1,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
close(fd);
memcpy(prt,msg,strlen(msg)+1);
munmap(prt,strlen(msg));
return 0;
}
~~~~~~~~~~~~~~~~~~我哥哥哥 哥哥哥 哥哥哥 哥哥哥~~~~~~~~~~~~~~~~~~~~~
gcc两个文件后开两个终端运行,先跑A,出现I am Process A,会睡10S,在此之际跑B,10S后,出现I am Process B。
网上找寻了多个例子运行,经常会发生段错误或是总线错误,通过GDB调试发现大多是由于分配的指针地址问题,例如无地址等,特此记录。
小例子:
*********************Process A******************************
#include <stdio.h>
#include <sys/mman.h> /* for mmap and munmap */
#include <sys/types.h> /* for open */
#include <sys/stat.h> /* for open */
#include <fcntl.h> /* for open */
#include <unistd.h> /* for lseek and write */
int main()
{
int fd,ret;
char *prt;
char *msg="I am Process A!\n";
/*记得加上 O_CREAT,没有该文件会自动创建,否则会报错*/
fd=open("/tmp/sharefile",O_RDWR|O_CREAT,00777);
if(fd==-1){
perror("open error!\n");
return 0;
}
/*truncate函数
表头文件:#include <unistd.h>
定义函数:int truncate(const char *path, off_t length);
函数说明:truncate()会将参数path指定的文件大小改为参数length指定的大小。
如果原来的文件大小比参数length大,则超过的部分会被删除
open函数创建的文件默认是大小为0的,无法进行映射,可以利用此函数写定其大小,也有采取lseek/write的方法
*/
如果原来的文件大小比参数length大,则超过的部分会被删除
open函数创建的文件默认是大小为0的,无法进行映射,可以利用此函数写定其大小,也有采取lseek/write的方法
*/
ret=truncate("/tmp/sharefile",4096);
prt=(char*) mmap(NULL,strlen(msg)+1,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(*prt == -1)
{
perror("mmap error!\n");
}
close(fd);
/*此时的memcpy就相当于利用write在写文件一样*/
memcpy(prt,msg,strlen(msg)+1);
printf("%s",prt);
sleep(10);
printf("%s",prt);
/*用完记得解除映射,资源利用完最好都回收做个环保的好孩子*/
munmap(prt,strlen(msg)+1);
return 0;
}
***************************Process B***********************************
#include <sys/mman.h> /* for mmap and munmap */
#include <sys/types.h> /* for open */
#include <sys/stat.h> /* for open */
#include <fcntl.h> /* for open */
#include <unistd.h> /* for lseek and write */
#include <stdio.h>
int main()
{
int fd,ret;
char *prt;
char *msg=" I am Process B!";
fd=open("/tmp/sharefile",O_RDWR|O_CREAT,00777);
if(fd==-1){
perror("open error!\n");
return 0;
}
/*查询文件状态如果文件存在可用就用不着创建了,这里定义mmap_file时候如果像文中是指针的一定要先分配地址,不然会有总线错误,或是直接别指针了,struct stat mmap_file就行,然后传进stat()时给地址&mmap_file,当然后面的if里内容也要变成mmap_file.st_size*/
struct stat *mmap_file;
mmap_file=(struct stat*)malloc(sizeof(struct stat));
ret=stat("/tmp/sharefile",mmap_file);
if(ret==-1){
perror("error!\n");
return 0;
}
if(mmap_file->st_size==0){
ret=truncate("/tmp/sharefile",4096);
}
prt=(char*) mmap(NULL,strlen(msg)+1,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
close(fd);
memcpy(prt,msg,strlen(msg)+1);
munmap(prt,strlen(msg));
return 0;
}
~~~~~~~~~~~~~~~~~~我哥哥哥 哥哥哥 哥哥哥 哥哥哥~~~~~~~~~~~~~~~~~~~~~
gcc两个文件后开两个终端运行,先跑A,出现I am Process A,会睡10S,在此之际跑B,10S后,出现I am Process B。