




已閱讀5頁,還剩6頁未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(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)核一個(gè)提示,應(yīng)該從什么地址開始映射,內(nèi)核會選擇addr之上的某個(gè)合適的地址開始映射。建立映射后,真正的映射首地址通過返回值可以得到。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多個(gè)進(jìn)程對同一個(gè)文件的映射是共享的,一個(gè)進(jìn)程對映射的內(nèi)存做了修改,另一個(gè)進(jìn)程也會看到這種變化。 MAP_PRIVATE多個(gè)進(jìn)程對同一個(gè)文件的映射不是共享的,一個(gè)進(jìn)程對映射的內(nèi)存做了修改,另一個(gè)進(jìn)程并不會看到這種變化,也不會真的寫到文件中去。如果mmap成功則返回映射首地址,如果出錯(cuò)則返回常數(shù)MAP_FAILED。當(dāng)進(jìn)程終止時(shí),該進(jìn)程的映射內(nèi)存會自動解除,也可以調(diào)用munmap解除映射。munmap成功返回0,出錯(cuò)返回-1。下面做一個(gè)簡單的實(shí)驗(yàn)。$ vi hello(編輯該文件的內(nèi)容為“hello”)$ od -tx1 -tc hello 0000000 68 65 6c 6c 6f 0a h e l l o n0000006現(xiàn)在用如下程序操作這個(gè)文件(注意,把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;然后再查看這個(gè)文件的內(nèi)容:$ od -tx1 -tc hello 0000000 33 32 31 30 6f 0a 3 2 1 0 o n 0000006請讀者自己分析一下實(shí)驗(yàn)結(jié)果。mmap函數(shù)的底層也是一個(gè)系統(tǒng)調(diào)用,在執(zhí)行程序時(shí)經(jīng)常要用到這個(gè)系統(tǒng)調(diào)用來映射共享庫到該進(jìn)程的地址空間。例如一個(gè)很簡單的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í)行這個(gè)程序要映射共享庫/lib/tls/i686/cmov/libc.so.6到進(jìn)程地址空間。也可以看到,printf函數(shù)的底層確實(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)核一個(gè)提示,應(yīng)該從什么地址開始映射,內(nèi)核會選擇addr之上的某個(gè)合適的地址開始映射。建立映射后,真正的映射首地址通過返回值可以得到。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多個(gè)進(jìn)程對同一個(gè)文件的映射是共享的,一個(gè)進(jìn)程對映射的內(nèi)存做了修改,另一個(gè)進(jìn)程也會看到這種變化。 MAP_PRIVATE多個(gè)進(jìn)程對同一個(gè)文件的映射不是共享的,一個(gè)進(jìn)程對映射的內(nèi)存做了修改,另一個(gè)進(jìn)程并不會看到這種變化,也不會真的寫到文件中去。如果mmap成功則返回映射首地址,如果出錯(cuò)則返回常數(shù)MAP_FAILED。當(dāng)進(jìn)程終止時(shí),該進(jìn)程的映射內(nèi)存會自動解除,也可以調(diào)用munmap解除映射。munmap成功返回0,出錯(cuò)返回-1。下面做一個(gè)簡單的實(shí)驗(yàn)。$ vi hello(編輯該文件的內(nèi)容為“hello”)$ od -tx1 -tc hello 0000000 68 65 6c 6c 6f 0a h e l l o n0000006現(xiàn)在用如下程序操作這個(gè)文件(注意,把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;然后再查看這個(gè)文件的內(nèi)容:$ od -tx1 -tc hello 0000000 33 32 31 30 6f 0a 3 2 1 0 o n 0000006請讀者自己分析一下實(shí)驗(yàn)結(jié)果。mmap函數(shù)的底層也是一個(gè)系統(tǒng)調(diào)用,在執(zhí)行程序時(shí)經(jīng)常要用到這個(gè)系統(tǒng)調(diào)用來映射共享庫到該進(jìn)程的地址空間。例如一個(gè)很簡單的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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 【正版授權(quán)】 ISO 2361:2025 EN Electrodeposited nickel coatings on magnetic and non-magnetic substrates - Measurement of coating thickness - Magnetic method
- 單方面諒解協(xié)議書范本
- 民宅供暖入網(wǎng)協(xié)議書范本
- 跨國并購企業(yè)戰(zhàn)略合作的框架協(xié)議
- 離婚協(xié)議書:婚姻解除與共同財(cái)產(chǎn)分割全案
- 智能制造財(cái)產(chǎn)權(quán)利質(zhì)押融資合同模板
- 高端汽車抵押擔(dān)保合同
- 臨時(shí)彩鋼房拆除作業(yè)安全管理合同
- 房地產(chǎn)交易場地價(jià)差額貨幣賠償合同
- 餐飲店面租賃及節(jié)假日促銷活動合作合同
- 碧桂園案場管理制度
- 房地產(chǎn)營銷績效評估與分析
- 2025年報(bào)關(guān)操作技巧與核心要點(diǎn)
- 兒童周末興趣活動方案
- 2024-2025學(xué)年人教版八年級數(shù)學(xué)下冊期末綜合復(fù)習(xí)解答壓軸題培優(yōu)提升專題訓(xùn)練+
- 2025-2030中國蒸氣產(chǎn)品行業(yè)市場發(fā)展趨勢與前景展望戰(zhàn)略研究報(bào)告
- DB62T 4130-2020 公路混凝土構(gòu)件蒸汽養(yǎng)護(hù)技術(shù)規(guī)程
- 洗浴中心保安合同范本
- (2025校招)人工智能工程師招聘筆試試題及答案
- 2024年四川省儀隴縣事業(yè)單位公開招聘中小學(xué)教師38名筆試題帶答案
- 2024年邢臺市市屬事業(yè)單位考試真題
評論
0/150
提交評論