linux mmap函数,mmap函数分析

mmap系统调用是将一个打开的文件映射到进程的用户空间,mmap系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以像访问普通内存一样对文件进行访问,不必再调用read(),write()等操作。

我们的程序中大量运用了mmap,用到的正是mmap的这种“像访问普通内存一样对文件进行访问”的功能。实践证明,当要对一个文件频繁的进行访问,并且指针来回移动时,调用mmap比用常规的方法快很多。

下面介绍mmap函数原型如下:

#include

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

addr:指定为文件描述符fd应被映射到的进程空间的起始地址。它通常被指定为一个空指针,这样告诉内核自己去选择起始地址。一般默认为NULL。

length:是映射到调用进程地址空间中的字节数,她从被映射文件开头offset个字节处开始算。

prot:负责保护内存映射区的保护。常用值是代表读写访问的PROT_READ | PROT_WRITE.当然还包括数据的执行(PROT_EXEC)、数据不可访问(PROT_NONE)

flags:flags常用值有MAP_SHARED或MAP_PRIVATE这两个标志必须选一个,并可以选上MAP_FIXED。如果指定了,那么调用进程对被映射数据所做的修改只对该进程可见,而不该变其底层支撑对象。如果指定了,那么调用进程对被映射数据所作的修改对于共享该对象的所有进程都可见,而且确实改变了其底层支撑对象。

参数fd为映射文件的描述符,offset为文件的起点,默认为0.

下面看一个实例:父子进程共享4字节匿名区

#include

3 #include

4 #define N 10

5 int main ()

6 {

7         int i,sum,fd;

8         int *result_ptr = mmap(NULL,4,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS,fd,0);

9 //      int pid=fork();

10         int pid=vfork();

11         if(pid==0)

12         {

13                 for(sum=0,i=1;i<=N;i++)

14                         sum+=i;

15                 *result_ptr = sum;

16

17         }else

18         {

19                 wait(0);

20                 printf("result=%d\n",*result_ptr);

21         }

22         return 0;

23

24 }

***@wuyaalan:~/code/kernel$ gcc -o mmap1 mmap1.c

***@wuyaalan:~/code/kernel$ ./mmap1

result=55

但是如果把fork换为vfork时,运行时会出现段错误,分析了下

***@wuyaalan:~/code/kernel$ gcc -o mmap1 mmap1.c

***@wuyaalan:~/code/kernel$ ./mmap1

段错误

***@wuyaalan:~/code/kernel$ gcc -g -rdynamic mmap1.c

***@wuyaalan:~/code/kernel$ gdb ./mmap1

GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2

Copyright (C) 2010 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law.  Type "show copying"

and "show warranty" for details.

This GDB was configured as "i686-linux-gnu".

For bug reporting instructions, please see:

...

Reading symbols from /home/yuyunchao/code/kernel/mmap1...(no debugging symbols found)...done.

(gdb) r

Starting program: /home/yuyunchao/code/kernel/mmap1

Program received signal SIGSEGV, Segmentation fault.

0x080484d7 in main ()

结果是访问了无效的内存。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值