zoukankan      html  css  js  c++  java
  • 使用mmap函数实现用户级存储器映射

    每个进程都有自己的虚拟地址空间,我们知道除了堆中的虚拟内存我们可以由程序员灵活分配和释放,其他的区域的虚拟内存都有系统控制,那么还有没有其他方法让程序员去灵活控制虚拟内存呢?linux下的mmap函数就此而来,mmap函数可以为我们在进程的虚拟空间开辟一块新的虚拟内存,你可以将一个文件映射到这块新的虚拟内存,所以操作新的虚拟内存就是操作这个文件,下面我将介绍mmap函数的运用。

    首先介绍mmap函数的头文件以及函数声明:

    #include <sys/mman.h>

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

    start表示新的虚拟内存从这个地址开始,一般来说取NULL,那么将有内核来分配

    length表示新的虚拟内存的大小

    prot表示这块新的虚拟内存的访问权限:

        PROT_EXEC:可执行

        PROT_READ:可读

        PROT_WRITE:可写

        PROT_NONE:无法访问

    flags表示 The flags argument determines whether updates to the mapping are visible to other  processes mapping the same region, and whether updates are carried through to the underlying file.  This behavior is determined by including exactly one of the following values in flags:
       MAP_SHARED Share  this  mapping.  Updates to the mapping are visible to other processes
                      that map this file, and are carried through to  the  underlying  file.   The
                      file may not actually be updated until msync(2) or munmap() is called.

           MAP_PRIVATE
                      Create a private copy-on-write mapping.  Updates to the mapping are not vis‐
                      ible to other processes mapping the same file, and are not  carried  through
                      to  the underlying file.  It is unspecified whether changes made to the file
                      after the mmap() call are visible in the mapped region.
    fd:被映射文件的文件描述符

    offset:从文件的offset处开始映射

    example:

           #include <sys/mman.h>
           #include <sys/stat.h>
           #include <fcntl.h>
           #include <stdio.h>
           #include <stdlib.h>
           #include <unistd.h>
    
           #define handle_error(msg) \
               do { perror(msg); exit(EXIT_FAILURE); } while (0)
    
           int
           main(int argc, char *argv[])
           {
               char *addr;
               int fd;
               struct stat sb;
               off_t offset, pa_offset;
               size_t length;
               ssize_t s;
    
               if (argc < 3 || argc > 4) {
                   fprintf(stderr, "%s file offset [length]\n", argv[0]);
                   exit(EXIT_FAILURE);
               }
    
               fd = open(argv[1], O_RDONLY);
               if (fd == -1)
                   handle_error("open");
    
               if (fstat(fd, &sb) == -1)           /* To obtain file size */
                   handle_error("fstat");
    
               offset = atoi(argv[2]);
               pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
                   /* offset for mmap() must be page aligned */
    
               if (offset >= sb.st_size) {
                   fprintf(stderr, "offset is past end of file\n");
                   exit(EXIT_FAILURE);
               }
    
               if (argc == 4) {
                   length = atoi(argv[3]);
                   if (offset + length > sb.st_size)
                           length = sb.st_size - offset;
                       /* Can't display bytes past end of file */
    
               } else {    /* No length arg ==> display to end of file */
                   length = sb.st_size - offset;
               }
    
               addr = mmap(NULL, length + offset - pa_offset, PROT_READ,
                           MAP_PRIVATE, fd, pa_offset);
               printf("addr is 0x%08x\n\n\n",&addr);
               if (addr == MAP_FAILED)
                   handle_error("mmap");
    
               s = write(STDOUT_FILENO, addr + offset - pa_offset, length);
               if (s != length) {
                   if (s == -1)
                       handle_error("write");
    
                   fprintf(stderr, "partial write");
                   exit(EXIT_FAILURE);
               }
    
               exit(EXIT_SUCCESS);
           } /* main */
  • 相关阅读:
    ORACLE 查找数据库中有记录的表
    [原]Asp.Net 错误:无法连接到Asp.Net Developement server
    中国移动手机话费查询号码1008611
    动手修改VS2008的解决方案文件,以让VS2005打开它
    [转]飞秋使用说明与常见问题解决方法
    微软发布Fix it 修复Windows 7等系统0day漏洞
    Oracle DECODE 函数应用示例
    [转]C#实现访问网络共享文件夹
    c#保留小数点后位数的方法
    [转]微软紧急修复高危漏洞 30万网民PC已遭攻击
  • 原文地址:https://www.cnblogs.com/GODYCA/p/2857693.html
Copyright © 2011-2022 走看看