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 */
  • 相关阅读:
    EditPlus使用技巧
    PL/SQL Dev的问题
    解决httpModules 未能从程序集 XX 加载类型 XXX 的错误
    IE浏览器无法显示背景,字体显示很大问题的解决办法[转]
    如何在Outlook2003中加入农历节气
    再谈Oracle在Windows下的权限问题
    Vista下安装布署注册的问题解决
    [转]关于管理的经典故事(员工激励)
    开始应用AJAX
    Aptana IDE 中文乱码的问题解决
  • 原文地址:https://www.cnblogs.com/GODYCA/p/2857693.html
Copyright © 2011-2022 走看看