文章目錄
一、mmap 創建內存映射代碼示例
1、fopen 打開或創建文件
2、lseek 設置文件大小
3、mmap 函數使用
4、munmap 刪除內存映射
二、完整代碼示例
一、mmap 創建內存映射代碼示例
1、fopen 打開或創建文件
使用 fopen 函數 , 打開一個文件 , 此時文件可能不存在 , 需要創建文件 ;
// 打開文件 fd = open(argv[1], O_CREAT | O_RDWR | O_TRUNC, 00777);
2、lseek 設置文件大小
通過 lseek 函數 , 設置文件的大小 , 將文件偏移 sizeof(student) * 10 - 1 大小 , 就是設置文件大小設置為 10 個 student 結構體大小
// 修改文件偏移量 , 將文件的讀寫位置指向文件頭后 , // 再增加 sizeof(student) * 10 - 1 偏移量 , 偏移量從 0 開始計算 , // 該操作的作用是將文件大小設置為 10 個 student 結構體大小 lseek(fd, sizeof(student) * 10 - 1, SEEK_SET);
3、mmap 函數使用
調用 mmap 函數 , 創建文件映射 , 相關參數作用如下 :
NULL : 映射區的開始地址
sizeof(student) * 1 : 文件映射區的長度
PROT_READ | PROT_WRITE : 內存保護的標志位 , 該內存頁的內容可以 讀取 寫入
MAP_SHARED : 指定映射關系 , 指的是該映射是進程的共享內存空間
fd : 文件描述符 , 被映射的文件
0 : 被映射文件的偏移量 , 從文件的哪個字節位置開始映射
如果返回 -1 指針 , 則說明 內存映射 創建失敗 ;
// 創建文件映射 // NULL : 映射區的開始地址 // sizeof(student) * 1 : 文件映射區的長度 // PROT_READ | PROT_WRITE : 內存保護的標志位 , 該內存頁的內容可以 讀取 寫入 // MAP_SHARED : 指定映射關系 , 指的是該映射是進程的共享內存空間 // fd : 文件描述符 , 被映射的文件 // 0 : 被映射文件的偏移量 , 從文件的哪個字節位置開始映射 p_student = (student*)mmap(NULL, sizeof(student) * 10, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); // mmap 文件映射創建失敗 if (p_student == (void*) - 1) { printf("mmap 文件映射創建失敗 !"); return -1; } // 創建完文件映射之后 , 文件描述符就可以釋放了 close(fd);
4、munmap 刪除內存映射
調用 munmap 函數 , 刪除 mmap 創建的 內存映射 ;
// 刪除文件映射 munmap(p_student, sizeof(student) * 10);
二、完整代碼示例
#include #include #include #include #include #include #include /* 定義一個結構體 代表 " 學生 " 結構體成員中設置一個 char* 字符串 和 int 類型數據 分別代表 學生的 姓名 和 年齡 */ typedef struct { char name[4]; // 姓名 int age; // 年齡 }student; int main(int argc, char** argv) { // 打開文件的 文件描述符 int fd; // 循環控制變量 int i; // 學生結構體指針 , 指向 student 結構體類型變量 student* p_student; // 用于生成姓名字符串 char name_char; // 打開文件 fd = open(argv[1], O_CREAT | O_RDWR | O_TRUNC, 00777); // 修改文件偏移量 , 將文件的讀寫位置指向文件頭后 , // 再增加 sizeof(student) * 10 - 1 偏移量 , 偏移量從 0 開始計算 , // 該操作的作用是將文件大小設置為 10 個 student 結構體大小 lseek(fd, sizeof(student) * 10 - 1, SEEK_SET); // 向文件中寫入數據 , 生成文件 write(fd, "", 1); // 創建文件映射 // NULL : 映射區的開始地址 // sizeof(student) * 1 : 文件映射區的長度 // PROT_READ | PROT_WRITE : 內存保護的標志位 , 該內存頁的內容可以 讀取 寫入 // MAP_SHARED : 指定映射關系 , 指的是該映射是進程的共享內存空間 // fd : 文件描述符 , 被映射的文件 // 0 : 被映射文件的偏移量 , 從文件的哪個字節位置開始映射 p_student = (student*)mmap(NULL, sizeof(student) * 10, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); // mmap 文件映射創建失敗 if (p_student == (void*) - 1) { printf("mmap 文件映射創建失敗 !"); return -1; } // 創建完文件映射之后 , 文件描述符就可以釋放了 close(fd); // 逐個字節拷貝 name_char = 'A'; for (i = 0; i < 10; i++) { // 將字符串的第 1 個字節設置為 '#include #include #include #include #include #include #include /* 定義一個結構體 代表 " 學生 " 結構體成員中設置一個 char* 字符串 和 int 類型數據 分別代表 學生的 姓名 和 年齡 */ typedef struct { char name[4]; // 姓名 int age; // 年齡 }student; int main(int argc, char** argv) { // 打開文件的 文件描述符 int fd; // 循環控制變量 int i; // 學生結構體指針 , 指向 student 結構體類型變量 student* p_student; // 用于生成姓名字符串 char name_char; // 打開文件 fd = open(argv[1], O_CREAT | O_RDWR | O_TRUNC, 00777); // 修改文件偏移量 , 將文件的讀寫位置指向文件頭后 , // 再增加 sizeof(student) * 10 - 1 偏移量 , 偏移量從 0 開始計算 , // 該操作的作用是將文件大小設置為 10 個 student 結構體大小 lseek(fd, sizeof(student) * 10 - 1, SEEK_SET); // 向文件中寫入數據 , 生成文件 write(fd, "", 1); // 創建文件映射 // NULL : 映射區的開始地址 // sizeof(student) * 1 : 文件映射區的長度 // PROT_READ | PROT_WRITE : 內存保護的標志位 , 該內存頁的內容可以 讀取 寫入 // MAP_SHARED : 指定映射關系 , 指的是該映射是進程的共享內存空間 // fd : 文件描述符 , 被映射的文件 // 0 : 被映射文件的偏移量 , 從文件的哪個字節位置開始映射 p_student = (student*)mmap(NULL, sizeof(student) * 10, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); // mmap 文件映射創建失敗 if (p_student == (void*) - 1) { printf("mmap 文件映射創建失敗 !"); return -1; } // 創建完文件映射之后 , 文件描述符就可以釋放了 close(fd); // 逐個字節拷貝 name_char = 'A'; for (i = 0; i < 10; i++) { // 將字符串的第 1 個字節設置為 '\0' , 這是 字符串的結尾 , // 第 0 個字節就是字符串的實際內容 , 該字符串只有 1 個字符 (*(p_student + i)).name[1] = '\0'; // 拷貝 字符串 到 p_student 指向的內存中 , 該內存是文件映射內存 // 拷貝內存的同時 , 也會修改文件內容 memcpy((*(p_student + i)).name, &name_char, 1); // 設置 (*(p_student + i)).age = 1 + i; // 生成不同的字符 , 用于生成不同的 name 字符串 name_char++; } printf("文件初始化完畢 !\n"); // 休眠 8 秒 sleep(8); // 刪除文件映射 munmap(p_student, sizeof(student) * 10); printf("mmap 文件映射展示完畢 !\n"); return 0; }
' , 這是 字符串的結尾 , // 第 0 個字節就是字符串的實際內容 , 該字符串只有 1 個字符 (*(p_student + i)).name[1] = '#include #include #include #include #include #include #include /* 定義一個結構體 代表 " 學生 " 結構體成員中設置一個 char* 字符串 和 int 類型數據 分別代表 學生的 姓名 和 年齡 */ typedef struct { char name[4]; // 姓名 int age; // 年齡 }student; int main(int argc, char** argv) { // 打開文件的 文件描述符 int fd; // 循環控制變量 int i; // 學生結構體指針 , 指向 student 結構體類型變量 student* p_student; // 用于生成姓名字符串 char name_char; // 打開文件 fd = open(argv[1], O_CREAT | O_RDWR | O_TRUNC, 00777); // 修改文件偏移量 , 將文件的讀寫位置指向文件頭后 , // 再增加 sizeof(student) * 10 - 1 偏移量 , 偏移量從 0 開始計算 , // 該操作的作用是將文件大小設置為 10 個 student 結構體大小 lseek(fd, sizeof(student) * 10 - 1, SEEK_SET); // 向文件中寫入數據 , 生成文件 write(fd, "", 1); // 創建文件映射 // NULL : 映射區的開始地址 // sizeof(student) * 1 : 文件映射區的長度 // PROT_READ | PROT_WRITE : 內存保護的標志位 , 該內存頁的內容可以 讀取 寫入 // MAP_SHARED : 指定映射關系 , 指的是該映射是進程的共享內存空間 // fd : 文件描述符 , 被映射的文件 // 0 : 被映射文件的偏移量 , 從文件的哪個字節位置開始映射 p_student = (student*)mmap(NULL, sizeof(student) * 10, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); // mmap 文件映射創建失敗 if (p_student == (void*) - 1) { printf("mmap 文件映射創建失敗 !"); return -1; } // 創建完文件映射之后 , 文件描述符就可以釋放了 close(fd); // 逐個字節拷貝 name_char = 'A'; for (i = 0; i < 10; i++) { // 將字符串的第 1 個字節設置為 '\0' , 這是 字符串的結尾 , // 第 0 個字節就是字符串的實際內容 , 該字符串只有 1 個字符 (*(p_student + i)).name[1] = '\0'; // 拷貝 字符串 到 p_student 指向的內存中 , 該內存是文件映射內存 // 拷貝內存的同時 , 也會修改文件內容 memcpy((*(p_student + i)).name, &name_char, 1); // 設置 (*(p_student + i)).age = 1 + i; // 生成不同的字符 , 用于生成不同的 name 字符串 name_char++; } printf("文件初始化完畢 !\n"); // 休眠 8 秒 sleep(8); // 刪除文件映射 munmap(p_student, sizeof(student) * 10); printf("mmap 文件映射展示完畢 !\n"); return 0; }
'; // 拷貝 字符串 到 p_student 指向的內存中 , 該內存是文件映射內存 // 拷貝內存的同時 , 也會修改文件內容 memcpy((*(p_student + i)).name, &name_char, 1); // 設置 (*(p_student + i)).age = 1 + i; // 生成不同的字符 , 用于生成不同的 name 字符串 name_char++; } printf("文件初始化完畢 !\n"); // 休眠 8 秒 sleep(8); // 刪除文件映射 munmap(p_student, sizeof(student) * 10); printf("mmap 文件映射展示完畢 !\n"); return 0; }
編譯并執行代碼 : 上述源碼保存在 mmap_demo_01.c 文件中 , 執行

gcc mmap_demo_01.c -o mmap_demo_01
命令 , 編譯上述源碼 , 并輸出可執行文件 mmap_demo_01 , 執行
./mmap_demo_01 file
命令 , 開始執行該應用程序 ;
執行結果如下 :
han@ubuntu:~/vscode/mmap$ gcc mmap_demo_01.c -o mmap_demo_01 han@ubuntu:~/vscode/mmap$ ./mmap_demo_01 file 文件初始化完畢 ! mmap 文件映射展示完畢 ! han@ubuntu:~/vscode/mmap$
Linux 項目管理 ProjectMan
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。