已閱讀5頁,還剩6頁未讀, 繼續(xù)免費閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第28章文件與I/O8.mmapmmap可以把磁盤文件的一部分直接映射到內(nèi)存,這樣文件中的位置直接就有對應(yīng)的內(nèi)存地址,對文件的讀寫可以直接用指針來做而不需要read/write函數(shù)。#include void *mmap(void *addr, size_t len, int prot, int flag, int filedes, off_t off); int munmap(void *addr, size_t len);該函數(shù)各參數(shù)的作用圖示如下:圖28.4.mmap函數(shù)如果addr參數(shù)為NULL,內(nèi)核會自己在進(jìn)程地址空間中選擇合適的地址建立映射。如果addr不是NULL,則給內(nèi)核一個提示,應(yīng)該從什么地址開始映射,內(nèi)核會選擇addr之上的某個合適的地址開始映射。建立映射后,真正的映射首地址通過返回值可以得到。len參數(shù)是需要映射的那一部分文件的長度。off參數(shù)是從文件的什么位置開始映射,必須是頁大小的整數(shù)倍(在32位體系統(tǒng)結(jié)構(gòu)上通常是4K)。filedes是代表該文件的描述符。prot參數(shù)有四種取值: PROT_EXEC表示映射的這一段可執(zhí)行,例如映射共享庫 PROT_READ表示映射的這一段可讀 PROT_WRITE表示映射的這一段可寫 PROT_NONE表示映射的這一段不可訪問flag參數(shù)有很多種取值,這里只講兩種,其它取值可查看mmap(2) MAP_SHARED多個進(jìn)程對同一個文件的映射是共享的,一個進(jìn)程對映射的內(nèi)存做了修改,另一個進(jìn)程也會看到這種變化。 MAP_PRIVATE多個進(jìn)程對同一個文件的映射不是共享的,一個進(jìn)程對映射的內(nèi)存做了修改,另一個進(jìn)程并不會看到這種變化,也不會真的寫到文件中去。如果mmap成功則返回映射首地址,如果出錯則返回常數(shù)MAP_FAILED。當(dāng)進(jìn)程終止時,該進(jìn)程的映射內(nèi)存會自動解除,也可以調(diào)用munmap解除映射。munmap成功返回0,出錯返回-1。下面做一個簡單的實驗。$ vi hello(編輯該文件的內(nèi)容為“hello”)$ od -tx1 -tc hello 0000000 68 65 6c 6c 6f 0a h e l l o n0000006現(xiàn)在用如下程序操作這個文件(注意,把fd關(guān)掉并不影響該文件已建立的映射,仍然可以對文件進(jìn)行讀寫)。#include #include #include int main(void)int *p;int fd = open(hello, O_RDWR);if (fd 0) perror(open hello);exit(1);p = mmap(NULL, 6, PROT_WRITE, MAP_SHARED, fd, 0);if (p = MAP_FAILED) perror(mmap);exit(1);close(fd);p0 = 0x30313233;munmap(p, 6);return 0;然后再查看這個文件的內(nèi)容:$ od -tx1 -tc hello 0000000 33 32 31 30 6f 0a 3 2 1 0 o n 0000006請讀者自己分析一下實驗結(jié)果。mmap函數(shù)的底層也是一個系統(tǒng)調(diào)用,在執(zhí)行程序時經(jīng)常要用到這個系統(tǒng)調(diào)用來映射共享庫到該進(jìn)程的地址空間。例如一個很簡單的hello world程序:#include int main(void)printf(hello worldn);return 0;用strace命令執(zhí)行該程序,跟蹤該程序執(zhí)行過程中用到的所有系統(tǒng)調(diào)用的參數(shù)及返回值:$ strace ./a.out execve(./a.out, ./a.out, /* 38 vars */) = 0brk(0) = 0x804a000access(/etc/ld.so.nohwcap, F_OK) = -1 ENOENT (No such file or directory)mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fca000access(/etc/ld.so.preload, R_OK) = -1 ENOENT (No such file or directory)open(/etc/ld.so.cache, O_RDONLY) = 3fstat64(3, st_mode=S_IFREG|0644, st_size=63628, .) = 0mmap2(NULL, 63628, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fba000close(3) = 0access(/etc/ld.so.nohwcap, F_OK) = -1 ENOENT (No such file or directory)open(/lib/tls/i686/cmov/libc.so.6, O_RDONLY) = 3read(3, 177ELF11100000000030301000260a1., 512) = 512fstat64(3, st_mode=S_IFREG|0644, st_size=1339816, .) = 0mmap2(NULL, 1349136, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e70000mmap2(0xb7fb4000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x143) = 0xb7fb4000mmap2(0xb7fb7000, 9744, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7fb7000close(3) = 0mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e6f000set_thread_area(entry_number:-1 - 6, base_addr:0xb7e6f6b0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1) = 0mprotect(0xb7fb4000, 4096, PROT_READ) = 0munmap(0xb7fba000, 63628) = 0fstat64(1, st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), .) = 0mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fc9000write(1, hello worldn, 12hello world) = 12exit_group(0) = ?Process 8572 detached可以看到,執(zhí)行這個程序要映射共享庫/lib/tls/i686/cmov/libc.so.6到進(jìn)程地址空間。也可以看到,printf函數(shù)的底層確實是調(diào)用write。 8.mmapmmap可以把磁盤文件的一部分直接映射到內(nèi)存,這樣文件中的位置直接就有對應(yīng)的內(nèi)存地址,對文件的讀寫可以直接用指針來做而不需要read/write函數(shù)。#include void *mmap(void *addr, size_t len, int prot, int flag, int filedes, off_t off); int munmap(void *addr, size_t len);該函數(shù)各參數(shù)的作用圖示如下:圖28.4.mmap函數(shù)如果addr參數(shù)為NULL,內(nèi)核會自己在進(jìn)程地址空間中選擇合適的地址建立映射。如果addr不是NULL,則給內(nèi)核一個提示,應(yīng)該從什么地址開始映射,內(nèi)核會選擇addr之上的某個合適的地址開始映射。建立映射后,真正的映射首地址通過返回值可以得到。len參數(shù)是需要映射的那一部分文件的長度。off參數(shù)是從文件的什么位置開始映射,必須是頁大小的整數(shù)倍(在32位體系統(tǒng)結(jié)構(gòu)上通常是4K)。filedes是代表該文件的描述符。prot參數(shù)有四種取值: PROT_EXEC表示映射的這一段可執(zhí)行,例如映射共享庫 PROT_READ表示映射的這一段可讀 PROT_WRITE表示映射的這一段可寫 PROT_NONE表示映射的這一段不可訪問flag參數(shù)有很多種取值,這里只講兩種,其它取值可查看mmap(2) MAP_SHARED多個進(jìn)程對同一個文件的映射是共享的,一個進(jìn)程對映射的內(nèi)存做了修改,另一個進(jìn)程也會看到這種變化。 MAP_PRIVATE多個進(jìn)程對同一個文件的映射不是共享的,一個進(jìn)程對映射的內(nèi)存做了修改,另一個進(jìn)程并不會看到這種變化,也不會真的寫到文件中去。如果mmap成功則返回映射首地址,如果出錯則返回常數(shù)MAP_FAILED。當(dāng)進(jìn)程終止時,該進(jìn)程的映射內(nèi)存會自動解除,也可以調(diào)用munmap解除映射。munmap成功返回0,出錯返回-1。下面做一個簡單的實驗。$ vi hello(編輯該文件的內(nèi)容為“hello”)$ od -tx1 -tc hello 0000000 68 65 6c 6c 6f 0a h e l l o n0000006現(xiàn)在用如下程序操作這個文件(注意,把fd關(guān)掉并不影響該文件已建立的映射,仍然可以對文件進(jìn)行讀寫)。#include #include #include int main(void)int *p;int fd = open(hello, O_RDWR);if (fd 0) perror(open hello);exit(1);p = mmap(NULL, 6, PROT_WRITE, MAP_SHARED, fd, 0);if (p = MAP_FAILED) perror(mmap);exit(1);close(fd);p0 = 0x30313233;munmap(p, 6);return 0;然后再查看這個文件的內(nèi)容:$ od -tx1 -tc hello 0000000 33 32 31 30 6f 0a 3 2 1 0 o n 0000006請讀者自己分析一下實驗結(jié)果。mmap函數(shù)的底層也是一個系統(tǒng)調(diào)用,在執(zhí)行程序時經(jīng)常要用到這個系統(tǒng)調(diào)用來映射共享庫到該進(jìn)程的地址空間。例如一個很簡單的hello world程序:#include int main(void)printf(hello worldn);return 0;用strace命令執(zhí)行該程序,跟蹤該程序執(zhí)行過程中用到的所有系統(tǒng)調(diào)用的參數(shù)及返回值:$ strace ./a.out execve(./a.out, ./a.out, /* 38 vars */) = 0brk(0) = 0x804a000access(/etc/ld.so.nohwcap, F_OK) = -1 ENOENT (No such file or directory)mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fca000access(/etc/ld.so.preload, R_OK) = -1 ENOENT (No such file or directory)open(/etc/ld.so.cache, O_RDONLY) = 3fstat64(3, st_mode=S_IFREG|0644, st_size=63628, .) = 0mmap2(NULL, 63628, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fba000close(3) = 0access(/etc/ld.so.nohwcap, F_OK) = -1 ENOENT (No such file or directory)open(/lib/tls/i686/cmov/libc.so.6, O_RDONLY) = 3read(3, 177ELF11100000000030301000260a1., 512) = 512fstat64(3, st_mode=S_IFREG|0644, st_size=1339816, .) = 0mmap2(NULL, 1349136, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e70000mmap2(0xb7fb4000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x143) = 0xb7fb4000mmap2(0xb7fb7000, 9744, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7fb7000close(3) = 0mmap2(NULL, 4
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二四年度中小企業(yè)適用勞動合同法免除條件協(xié)議書3篇
- 二零二五年度水利工程鋼管腳手架搭設(shè)及質(zhì)量保障合同4篇
- 個人交易知識產(chǎn)權(quán)許可使用合同(2024版)3篇
- 2025年度航空航天器密封打膠工程合同書4篇
- 二零二五年度高性能玻璃鋼GRG、FRP制品采購合同2篇
- 2025年度農(nóng)戶農(nóng)村合作醫(yī)療基金借款合同范本4篇
- 二零二五年度企業(yè)員工心理素質(zhì)培訓(xùn)合同
- 基于2025年度目標(biāo)的農(nóng)業(yè)品牌營銷合同3篇
- 2025版二零二五苗木市場推廣與銷售代理合同4篇
- 2025年度紡織面料環(huán)保認(rèn)證與市場推廣合同4篇
- 完整版秸稈炭化成型綜合利用項目可行性研究報告
- 油氣行業(yè)人才需求預(yù)測-洞察分析
- 《數(shù)據(jù)采集技術(shù)》課件-Scrapy 框架的基本操作
- 2025年河北省單招語文模擬測試二(原卷版)
- 高一化學(xué)《活潑的金屬單質(zhì)-鈉》分層練習(xí)含答案解析
- DB34∕T 4010-2021 水利工程外觀質(zhì)量評定規(guī)程
- 2024年內(nèi)蒙古中考英語試卷五套合卷附答案
- 2024年電工(高級)證考試題庫及答案
- 農(nóng)產(chǎn)品質(zhì)量評估與分級
- 儲能電站火災(zāi)應(yīng)急預(yù)案演練
- 人教版(新插圖)二年級下冊數(shù)學(xué) 第4課時用“進(jìn)一法”和“去尾法”解決簡單的實際問題 教學(xué)課件
評論
0/150
提交評論