日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

3Linux内存映射,mmap()函数

發布時間:2024/9/27 linux 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 3Linux内存映射,mmap()函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


1mmap()依賴的頭文件

#include <sys/mman.h>

2函數聲明:

void *mmap(void *addr, size_t length, intprot, int flags,

???? intfd, off_t offset);

int munmap(void *addr, size_t length);

函數說明:

mmap可以把磁盤文件的一部分直接映射到內存,這樣文件中的位置直接就有對應的內存

地址,對文件的讀寫可以直接用指針來做而不需要read/write函數。

3.內存映射圖:


說明:

如果addr參數為NULL,內核會自己在進程地址空間中選擇合適的地址建立映射。如果

addr不是NULL,則給內核一個提示,應該從什么地址開始映射,內核會選擇addr之上的某個合適的地址開始映射。建立映射后,真正的映射首地址通過返回值可以得到。len參數是需要映射的那一部分文件的長度。off參數是從文件的什么位置開始映射,必須是頁大小的整數倍(在32位體系統結構上通常是4K)。filedes是代表該文件的描述符。

prot參數有四種取值:

* PROT_EXEC表示映射的這一段可執行,例如映射共享庫

* PROT_READ表示映射的這一段可讀

* PROT_WRITE表示映射的這一段可寫

* PROT_NONE表示映射的這一段不可訪問

flag參數有很多種取值,這里只講兩種,其它取值可查看mmap(2)

* MAP_SHARED多個進程對同一個文件的映射是共享的,一個進程對映射的內存做了修

改,另一個進程也會看到這種變化。

* MAP_PRIVATE多個進程對同一個文件的映射不是共享的,一個進程對映射的內存做了修改,另一個進程并不會看到這種變化,也不會真的寫到文件中去。

如果mmap成功則返回映射首地址,如果出錯則返回常數MAP_FAILED。當進程終止時,該進程的映射內存會自動解除,也可以調用munmap解除映射。munmap成功返回0,出錯返回-1。

下面做一個簡單的實驗

xingwenpeng@ubuntu:~$ vi hello

xingwenpeng@ubuntu:~$ cat hello

helloworld

xingwenpeng@ubuntu:~$ od -tx1 -tc hello

0000000 68 65 6c 6c 6f 77 6f 72 6c 64 0a

h ?e ?l ?l o w?o ?r ?l ?d \n

0000013

?

使用mmap映射

#include <stdlib.h>

#include <sys/mman.h>

#include <fcntl.h>

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);

p[0] = 0x30313233;

munmap(p, 6);

return 0;

}

案例2

寫端案例(注意要傳遞進去一個已經存在的文件名):

#include<stdio.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<sys/mman.h>

#include<unistd.h>

#include<stdlib.h>

#include<fcntl.h>

?

#define MAPLEN 0x1000

?

void sys_err(char *str,int exitno)

{

???perror(str);

???exit(exitno);

}

?

int main(int argc,char *argv[])

{

???char *mm;

???int fd,i = 0;

???if(argc < 2)

??? {

???????printf("./a.out filename\n");

???????exit(1);

??? }

???fd = open(argv[1],O_RDWR|O_CREAT,0777);

???if(fd < 0)

??? {

???????sys_err("open",1);

??? }

???if(lseek(fd,MAPLEN-1,SEEK_SET) < 0)

??? {

???????sys_err("lseek",3);

??? }

???if(write(fd,"\0",1) < 0)

??? {

???????sys_err("write",4);

??? }

?

//使用MAP_SHARED共享的方式,也就是說:內存或磁盤文件中的一者發生內容變化

???mm = mmap(NULL,MAPLEN,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

???if(mm == MAP_FAILED){

???????sys_err("mmap",2);

??? }

?

???close(fd);

?

???while(1)

??? {

???????sprintf(mm,"hello%d",i++);

???????sleep(1);

??? }

?

???munmap(mm,MAPLEN);

???return 0;

}

讀端的案例:

#include<stdio.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<sys/mman.h>

#include<unistd.h>

#include<stdlib.h>

#include<fcntl.h>

?

#define MAPLEN 0x1000

void sys_err(char *str,int exitno)

{

???perror(str);

???exit(exitno);

}

?

int main(int argc,char *argv[])

{

???char *mm;

???int fd,i = 0;

???if(argc < 2)

??? {

???????printf("./a.out filname\n");

???????exit(1);

??? }

???fd = open(argv[1],O_RDWR);

???if(fd < 0)

??? {

???????sys_err("open",1);

??? }

???

???mm = mmap(NULL,MAPLEN,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

???if(mm == MAP_FAILED)

??? {

???????sys_err("mmap",2);

??? }

?

???close(fd);

?

???while(1)

??? {

???????printf("%s\n",mm);

???????sleep(1);

??? }

??? munmap(mm,MAPLEN);

???return 0;

}

?

總結

以上是生活随笔為你收集整理的3Linux内存映射,mmap()函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。