什么是mmap()函數(shù),很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
達孜ssl適用于網(wǎng)站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!
mmap()函數(shù)將一個文件或者其它對象映射盡內(nèi)存。文件被映射到多個頁上,如果文件的大小不是所有頁的大小之和,最后一個頁不被使用的空間將會清零。 mmap()系統(tǒng)調(diào)用使得進程之間通過映射同一個普通文件實現(xiàn)共享內(nèi)存。普通文件被映射到進程地址空間后,進程可以像訪問普通內(nèi)存一樣對文件進行訪問,不必再調(diào)用read(),write()等操作。
注:實際上,mmap()系統(tǒng)調(diào)用并不是完全為了共享內(nèi)存而設(shè)計的。它本身提供了不同于一般對普通文件的訪問方式,進程可以像讀寫內(nèi)存一樣對普通文件操作。POSIX或系統(tǒng)V的共享內(nèi)存IPC則純粹用于提供共享的目地,當然mmap()實現(xiàn)共享內(nèi)存也是其主要應(yīng)用之一。
Mmap()函數(shù)主要有3個用途:將一個普通文件映射到內(nèi)存中,通常在需要對文件進行頻繁讀寫操作時使用,這樣用內(nèi)存讀寫取代I/O讀寫,以獲得較高的性能將特殊文件進行匿名內(nèi)存映射,可以為關(guān)聯(lián)進程提供共享內(nèi)存空間為無關(guān)聯(lián)的進程提供共享內(nèi)存空間,一般也是將一個普通文件映射到內(nèi)存。 Linux提供了內(nèi)存映射函數(shù)mmap,它把文件內(nèi)容映射到一段內(nèi)存上(準確來說是虛擬內(nèi)存上),通過對著段內(nèi)存的讀取和修改,實現(xiàn)對文件的讀取和修改。
一、mmap()函數(shù)的用法
#include Void*mmap(void *start, size_t length, int port, int flags, int fd,off_t offsize);
參數(shù)的意義: Start:指向欲映射的內(nèi)存初始地址,通常設(shè)為NULL,代表讓系統(tǒng)自動選定地址,映射成功后返回該地址。 Length: 代表將文件中的多大的部分映射到內(nèi)存。 Port: 映射區(qū)域的保護方式 PROT_EXEC映射區(qū)域可被執(zhí)行 PROT_READ映射區(qū)域可被讀取 PROT_WRITE映射區(qū)域可被寫入 PROT_NONE映射區(qū)域不能存取 Flags:影響映射區(qū)域的各種屬性。在調(diào)用mmap()時必須指定MAP_SHARED或MAP_PRIVATE MAP_FIXED如果參數(shù)start所指的地址無法成功建立映射時,則放棄映射,不對地址做修正。 MAP_SHARED對映射區(qū)域的寫入數(shù)據(jù)會復(fù)制會文件內(nèi),而且允許其它映射文件的進程共享。 MAP_PRIVATE對映射區(qū)域的寫入操作會產(chǎn)生一個映射文件的復(fù)制,即私人的“寫時復(fù)制”對此區(qū)域的任何修改都不會寫回原來的文件內(nèi)容。 MAP_ANONYMOUS建立匿名映射。此時會忽略參數(shù)fd,不涉及文件,而且映射區(qū)域無法和其他進程共享。 MAP_DENYWRITE只允許對映射區(qū)域的寫入操作,其他對文件直接寫入的操作將會被拒絕。 MAP_LOCKED將映射區(qū)域鎖定住,這表示該區(qū)域不會被置換(swap)。 fd:要映射到內(nèi)存中的文件描述符。如果使用匿名內(nèi)存映射時,即flags中設(shè)置了MAP_ANONYMOUS,fd設(shè)為-1。有些系統(tǒng)不支持匿名內(nèi)存映射,則可以使用fopen打開/dev/zero文件,然后對該文件進行映射,可以同樣達到匿名內(nèi)存映射的效果。 offset:文件映射的偏移量,通常設(shè)置為0,代表從文件最前方開始對應(yīng),offset必須是分頁大小的整數(shù)倍。 返回值:若映射成功則返回映射區(qū)的內(nèi)存起始地址,否則返回MAP_FAILED(-1),錯誤原因存于errno 中。
二、系統(tǒng)調(diào)用mmap()用于共享內(nèi)存的兩種方式:(1)使用普通文件提供的內(nèi)存映射: 適用于任何進程之間。此時,需要打開或創(chuàng)建一個文件,然后再調(diào)用mmap() 典型調(diào)用代碼如下:
fd=open(name, flag, mode);if(fd<0) ... ptr=mmap(NULL, len ,PROT_READ|PROT_WRITE, MAP_SHARED , fd , 0);
(2)使用特殊文件提供匿名內(nèi)存映射: 適用于具有親緣關(guān)系的進程之間。由于父子進程特殊的親緣關(guān)系,在父進程中先調(diào)用mmap(),然后調(diào)用fork()。那么在調(diào)用fork()之后,子進程繼承父進程匿名映射后的地址空間,同樣也繼承mmap()返回的地址,這樣,父子進程就可以通過映射區(qū)域進行通信了。注意,這里不是一般的繼承關(guān)系。一般來說,子進程單獨維護從父進程繼承下來的一些變量。而mmap()返回的地址,卻由父子進程共同維護。對于具有親緣關(guān)系的進程實現(xiàn)共享內(nèi)存最好的方式應(yīng)該是采用匿名內(nèi)存映射的方式。此時,不必指定具體的文件,只要設(shè)置相應(yīng)的標志即可。
三、一個用mmap函數(shù)進行文件拷貝的例子* 用open系統(tǒng)調(diào)用打開文件,并返回描述符fd。這里要注意使用truncate函數(shù)來確定要寫入文件的大小。一般是用stat系列的函數(shù)來獲取源文件的大小,然后通過truncate函數(shù)修改目的文件的大小。
fd_s = open("2.c", O_RDONLY, S_IRUSR | S_IWUSR); fd_d = open("file.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); //獲取文件屬性 fstat(fd_s, &m_stat); //修改文件的大小 truncate("file.txt", m_stat.st_size);
* 用mmap建立內(nèi)存映射,并返回映射首地址指針start.
s_ptr = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd_s, 0); d_ptr = mmap(NULL, len, PROT_WRITE | PROT_READ, MAP_SHARED, fd_d, 0); if (d_ptr == MAP_FAILED) { printf("mmap error: %s\n", strerror(errno)); return ; }
* 對映射(文件)進行各種操作, 顯示(printf),修改(sprintf)。這里是用memcpy()函數(shù)實現(xiàn)文件的拷貝
memcpy(d_ptr, s_ptr, len);
* 用munmap(void *start, size_tlenght)關(guān)閉內(nèi)存映射.
munmap(s_ptr, len); munmap(d_ptr, len);
* 用close系統(tǒng)調(diào)用關(guān)閉文件fd. 自己再寫這個程序的時候又到了一個比較奇葩的問題。程序?qū)懞脮r運行的錯誤是段錯誤,調(diào)式發(fā)現(xiàn)是memcpy函數(shù)拷貝出錯。然后我回過頭來檢查代碼,發(fā)現(xiàn)程序沒有什么問題,然后又運行了一遍,錯誤變成了:mmaperror: bad filedescriptor。然后我就進行了調(diào)試,結(jié)果發(fā)現(xiàn)是第二個調(diào)用mmap函數(shù)的返回值是-1,也就是說沒有返回正確的初始地址。這兩次不一樣的錯誤讓我迷惑了,所以就找到了大神給看看代碼,結(jié)果大神剛坐下,運行程序就正確了,沒有做任何修改,這真的就是傳說中的人品問題嗎?不理解!然后我們謝了個腳本,讓程序執(zhí)行1000次,看看會不會又一次出錯的幾率,但是執(zhí)行下來仍然沒有任何錯誤,大神默默離開了。。一直都想不明白這兩次錯誤是怎樣產(chǎn)生的?有時怎樣自動變?yōu)檎_的?真是費解,還請高手指導(dǎo)。~~~~
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。
本文標題:什么是mmap()函數(shù)
轉(zhuǎn)載注明:http://www.rwnh.cn/article6/jipeig.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、網(wǎng)站收錄、小程序開發(fā)、網(wǎng)站建設(shè)、Google、做網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)