共享內存映射mmap筆記

共享內存映射mmap筆記

創建映射區:mmap函數原型

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

參數

  1. addr:指定映射區首地址,通常穿NULL
  2. length:共享內存映射區大小
  3. prot:共享內存映射區的讀寫屬性,PROT_READ,PROT_WRITE,PROT_READ|PROT_WRITE
  4. flags:標註共享內存的(進程間)共享屬性,MAP_SHARED,MAP_PRIVATE
  5. fd:用於創建共享內存映射區的那個文件的文件描述符
  6. offset:偏移量,必須是4k的整數倍

返回值

  1. 成功:映射區首地址
  2. 失敗:MAP_FAILED,errno

釋放映射區:munmap函數原型

int munmap(void *addr, size_t length);

參數

  1. addr:mmap的返回值
  2. length:映射區大小

示例代碼

#include <iostream>
#include <string>

#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <pthread.h>

void sys_err(const std::string& str) {
    perror(str.c_str());
    exit(1);
}

int main(void)
{
    //文件映射指針
    char* p = nullptr;
    //文件描述符
    int fd;
    fd = open("testmap.tmp", O_RDWR | O_CREAT | O_TRUNC, 0644);
    if (fd == -1) {
        sys_err("open error");
    }
    //文件擴展大小
    ftruncate(fd, 100);
    int len = lseek(fd, 0, SEEK_END);
    //創建映射區
    p = (char*)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);//C++中需要類型轉換
    if (p == MAP_FAILED) {
        sys_err("mmap error");
    }
    //關閉文件描述符
    close(fd);
    //使用p對文件進行寫操作
    strcpy(p, "========HELLO========");
    //查看p
    printf("%s", p);

    //釋放映射區
    int ret = munmap(p, len);
    if(ret == -1){
         sys_err("munmap error");
    }
    return 0;
}

注意事項

  1. 用於創建映射區的文件大小爲0,實際指定非0大小創建映射區,總線錯誤
  2. 用於創建映射區的文件大小爲0,實際指定0大小創建映射區,無效參數
  3. 用於創建映射區的文件屬性只讀,映射區屬性讀寫,無效參數
  4. 創建映射區需要read權限,mmap的讀寫權限要<=文件的open權限,mmap只寫是不行的
  5. 創建完映射區就可以關閉文件描述符
  6. offset必須是4096的整數倍(4k)
  7. 映射區訪問權限設爲MAP_PRIVATE,對內存操作不反映在磁盤上
  8. 映射區訪問權限設爲MAP_PRIVATE,只需要open文件時,有讀寫權限,用於創建映射區即可

mmap匿名映射區

不在磁盤上對文件有操作

例子

#include <iostream>
#include <string>

#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <pthread.h>

void sys_err(const std::string& str) {
    perror(str.c_str());
    exit(1);
}

int main(void)
{
    //文件映射指針
    char* p = nullptr;
    //創建映射區
    int len = 100;
    //注意一定要有MAP_ANON參數
    p = (char*)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); //C++中需要類型轉換
    if (p == MAP_FAILED) {
        sys_err("mmap error");
    }
    //寫操作
    strcpy(p, "99999");
    //查看p
    printf("%s", p);

    //釋放映射區
    int ret = munmap(p, len);
    if (ret == -1) {
        sys_err("munmap error");
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章