mmap学习过程中的一些小问题

mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。

具体函数定义如下:

#include <sys/mman.h>
/*映射函数*/
void *mmap(void *start, size_t length, int prot, int flags,int fd, off_t offset);

/*解除映射函数*/
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函数
    表头文件:#include <unistd.h>
   定义函数:int truncate(const char *path, off_t length);
   函数说明:truncate()会将参数path指定的文件大小改为参数length指定的大小。
   如果原来的文件大小比参数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。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值