【Linux 內核 內存管理】內存管理系統調用 ④ ( 代碼示例 | mmap 創建內存映射 | munmap 刪除內存映射 )

      網友投稿 885 2025-03-31

      文章目錄

      一、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 文件中 , 執行

      【Linux 內核 內存管理】內存管理系統調用 ④ ( 代碼示例 | mmap 創建內存映射 | munmap 刪除內存映射 )

      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小時內刪除侵權內容。

      上一篇:絕對定位(position:absolute)完美定位布局
      下一篇:請問:我已經編輯了一篇文檔,有很多格式,以后都想使用這樣的格式(包括正文,標題1,標題2等等,怎樣才
      相關文章
      亚洲6080yy久久无码产自国产| 青青草原亚洲视频| 亚洲人成色7777在线观看| 亚洲一本一道一区二区三区| 亚洲偷自精品三十六区| 亚洲国产成人久久三区| 亚洲老熟女@TubeumTV| 久久久久亚洲AV片无码下载蜜桃 | 亚洲AV成人精品网站在线播放| 亚洲一区二区三区影院| 在线播放亚洲第一字幕| 亚洲精品WWW久久久久久| 亚洲成A人片在线观看中文| 无码欧精品亚洲日韩一区夜夜嗨| 国产精品亚洲五月天高清| 午夜亚洲福利在线老司机| 亚洲精品97久久中文字幕无码| 亚洲伊人久久综合中文成人网| 中文字幕久久亚洲一区| 国产亚洲精品a在线观看| 亚洲熟女一区二区三区| 亚洲AV永久纯肉无码精品动漫 | 久久亚洲国产伦理| 亚洲三级电影网站| 亚洲妇女水蜜桃av网网站| 中文文字幕文字幕亚洲色| 亚洲国产成人精品无码区二本| 国产精品亚洲一区二区三区久久 | 久久亚洲国产精品五月天婷| 亚洲熟女少妇一区二区| 久久国产精品亚洲一区二区| 亚洲综合在线观看视频| 亚洲伊人久久大香线蕉影院| 亚洲日韩一区精品射精| 国产亚洲精品欧洲在线观看| 丁香五月亚洲综合深深爱| 亚洲AV无码成人精品区蜜桃| 亚洲精品中文字幕麻豆| ASS亚洲熟妇毛茸茸PICS| www国产亚洲精品久久久| 亚洲午夜久久久久妓女影院 |