中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

什么是mmap()函數(shù)

什么是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)

成都定制網(wǎng)站建設(shè)
红原县| 蓬莱市| 孝昌县| 双桥区| 仲巴县| 平果县| 巨鹿县| 江北区| 句容市| 嘉荫县| 鱼台县| 叶城县| 密云县| 城口县| 香河县| 新源县| 儋州市| 上犹县| 鹤山市| 扶余县| 连江县| 若羌县| 德令哈市| 江安县| 德州市| 河曲县| 阜新| 九龙坡区| 克山县| 宜章县| 思南县| 绩溪县| 双流县| 广元市| 阳东县| 开阳县| 嘉兴市| 利川市| 波密县| 贵德县| 洛宁县|