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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

共享内存简介和mmap 函数

發布時間:2025/7/25 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 共享内存简介和mmap 函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、共享內存簡介

共享內存區是最快的IPC形式,這些進程間數據傳遞不再涉及到內核,換句話說是進程不再通過執行進入內核的系統調用來傳遞彼此的數據。


即每個進程地址空間都有一個共享存儲器的映射區,當這塊區域都映射到相同的真正的物理地址空間時,可以通過這塊區域進行數據交換,例如共享庫就是這么實現的,很多進程都會使用同一個函數如printf,也許在真正的物理地址空間中只存在一份printf.o ,然后所有進程都映射到這一份printf.o 就實現了共享。


用管道或者消息隊列傳遞數據:


用共享內存傳遞數據:


即使用共享內存傳遞數據比用消息隊列和管道來說,減少了進入內核的次數,提高了效率。


二、mmap 函數

#include <sys/mman.h>

功能:將文件或者設備空間映射到共享內存區。
原型?void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
參數
addr: 要映射的起始地址,通常指定為NULL,讓內核自動選擇
len:映射到進程地址空間的字節數
prot:映射區保護方式
flags:標志
fd:文件描述符
offset:從文件頭開始的偏移量,必須是頁大小的整數倍(在32位體系統結構上通常是4K)
返回值:成功返回映射到的內存區的起始地址;失敗返回-1


prot 參數取值:

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

PROT_READ 表示映射的這一段可讀

PROT_WRITE 表示映射的這一段可寫

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


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

MAP_SHARED 多個進程對同一個文件的映射是共享的,一個進程對映射的內存做了修改,另一個進程也會看到這種變化。

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


內存映射文件示意圖:


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

功能:取消mmap函數建立的映射
原型?int munmap(void *addr, size_t len);
參數
addr: 映射的內存起始地址
len:映射到進程地址空間的字節數
返回值:成功返回0;失敗返回-1


下面寫兩個程序測試一下:

mmap_write.c

?

C++ Code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
? #include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/types.h>
#include<unistd.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/mman.h>

#define?ERR_EXIT(m)?\
????do?{?\
????????perror(m);?\
????????exit(EXIT_FAILURE);?\
????}?while(0)

typedef?struct?stu
{
????char?name[4];
????int?age;
}?STU;

int?main(int?argc,?char?*argv[])
{
????if?(argc?!=?2)
????{
????????fprintf(stderr,?"Usage:?%s?<file>\n",?argv[0]);
????????exit(EXIT_FAILURE);
????}

????int?fd;
????fd?=?open(argv[1],?O_CREAT?|?O_RDWR?|?O_TRUNC,?0666);
????if?(fd?==?-1)
????????ERR_EXIT("open");

????lseek(fd,?sizeof(STU)?*?5?-?1,?SEEK_SET);
????write(fd,?"",?1);

????STU?*p;
????p?=?(STU?*)mmap(NULL,?sizeof(STU)?*?5,?PROT_READ?|?PROT_WRITE,
????????????????????MAP_SHARED,?fd,?0);

????if?(p?==?-1)
????????ERR_EXIT("mmap");

????char?ch?=?'a';
????int?i;
????for?(i?=?0;?i?<?5;?i++)
????{
????????memcpy((p?+?i)->name,?&ch,?1);
????????(p?+?i)->age?=?20?+?i;
????????ch++;
????}

????printf("initialize?over\n");

????munmap(p,?sizeof(STU)?*?5);
????printf("exit...\n");
????return?0;
}

?

mmap_read.c

?

C++ Code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
? #include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/types.h>
#include<unistd.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/mman.h>

#define?ERR_EXIT(m)?\
????do?{?\
????????perror(m);?\
????????exit(EXIT_FAILURE);?\
????}?while(0)

typedef?struct?stu
{
????char?name[4];
????int?age;
}?STU;

int?main(int?argc,?char?*argv[])
{
????if?(argc?!=?2)
????{
????????fprintf(stderr,?"Usage:?%s?<file>\n",?argv[0]);
????????exit(EXIT_FAILURE);
????}

????int?fd;
????fd?=?open(argv[1],?O_RDWR);
????if?(fd?==?-1)
????????ERR_EXIT("open");


????STU?*p;
????p?=?(STU?*)mmap(NULL,?sizeof(STU)?*?5,?PROT_READ?|?PROT_WRITE,
????????????????????MAP_SHARED,?fd,?0);

????if?(p?==?-1)
????????ERR_EXIT("mmap");

????int?i;
????for?(i?=?0;?i?<?5;?i++)
????{
????????printf("name?=?%s?age?=?%d\n",?(p?+?i)->name,?(p?+?i)->age);
????}
????munmap(p,?sizeof(STU)?*?5);
????printf("exit...\n");
????return?0;
}

?

先運行mmap_write ,然后用od -c 查看文件內容:

?

simba@ubuntu:~/Documents/code/linux_programming/UNP/system_v$ ./mmap_write test?
initialize over
exit...
simba@ubuntu:~/Documents/code/linux_programming/UNP/system_v$ od -c test?
0000000 ? a ?\0 ?\0 ?\0 024 ?\0 ?\0 ?\0 ? b ?\0 ?\0 ?\0 025 ?\0 ?\0 ?\0
0000020 ? c ?\0 ?\0 ?\0 026 ?\0 ?\0 ?\0 ? d ?\0 ?\0 ?\0 027 ?\0 ?\0 ?\0
0000040 ? e ?\0 ?\0 ?\0 030 ?\0 ?\0 ?\0
0000050 注意od -c 輸出的是八進制,024即20,即對內存的操作寫入了文件。
再嘗試運行mmap_read,輸出如下: simba@ubuntu:~/Documents/code/linux_programming/UNP/system_v$ ./mmap_read test?
name = a age = 20
name = b age = 21
name = c age = 22
name = d age = 23
name = e age = 24
exit...
simba@ubuntu:~/Documents/code/linux_programming/UNP/system_v$?

再次將文件test 映射到內存,然后從內存讀取到了文件的內容。


mmap 編程注意點:

1、映射不能改變文件的大小;
2、可用于進程間通信的有效地址空間不完全受限于被映射文件的大小;
3、文件一旦被映射后,所有對映射區域的訪問實際上是對內存區域的訪問。映射區域內容寫回文件時,所寫內容不能超過文件的大小;


對于1,3點,將mmap_write.c 中40行以后的代碼中的5改成10,即映射的內存大于文件的大小,這樣寫入是不會出錯的,因為是向內存寫入,但用od 查看時發現文件還是40 個字節,即只有前5個STU才被真正寫入到了文件。

對于第2點,將mmap_write.c 和 mmap_read.c 都按上面說的更改成10,然后在mmap_write.c 中munmap 函數之前sleep(10); 先運行mmap_write,再在另一終端運行mmap_read,觀察結果:

simba@ubuntu:~/Documents/code/linux_programming/UNP/system_v$ ./mmap_read test?
name = a age = 20
name = b age = 21
name = c age = 22
name = d age = 23
name = e age = 24
name = f age = 25
name = g age = 26
name = h age = 27
name = i age = 28
name = j age = 29
exit...

即在mmap_write 對映射內存區域寫入之后尚未取消映射時,mmap_read 也映射了test 文件,兩個虛擬進程地址空間的映射區域都指向了同一塊物理內存,所以也能讀到write 進程對內存的修改,但進程結束后查看test 文件,還是40個字節而已。內存的映射是以頁面為單位的,一般為4k,所以才有第2條的說法,其實這才是真正體現共享內存可以進程間通信的所在。


最后一點,與write 類似,將文件映射到內存后對內存進行寫入,不一定會馬上寫回文件,有可能內核也會產生一個緩沖區,找個適當的時間內核再寫回設備文件,write 之后可以調用fsync 進行同步,同樣地,mmap 可以調用msync 進行同步。


?

參考:

《linux c 編程一站式學習》

《UNP》

總結

以上是生活随笔為你收集整理的共享内存简介和mmap 函数的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 少妇肥臀大白屁股高清 | 久久久久久香蕉 | 欧美成人午夜精品免费 | 永久免费av | 黄色片一级 | 一区二区视频国产 | www视频在线观看 | 五月天爱爱 | 国产欧美精品国产国产专区 | 午夜成年视频 | 人人爽人人做 | 国产精品二区视频 | 精品国产www| 亚洲v在线观看 | 亚洲熟女乱综合一区二区 | 国产成人精品在线视频 | 少妇人妻一区二区三区 | 中国三级视频 | 在线看毛片网站 | 国产精品字幕 | 亚洲黄色av | 16一17女人毛片 | 亚洲精品66 | 日韩av三区 | 91天天干 | 天天操天天操天天干 | 亚洲不卡视频 | 91尤物视频在线观看 | 嫩草天堂 | 中文字幕在线天堂 | 国产自产自拍 | 6090伦理| 欧美性视频在线 | 污片网站在线观看 | 任我爽在线 | 国产日韩精品suv | 一区免费视频 | 99热这| 欧亚av| 国产亚洲精品精品国产亚洲综合 | 海角国产乱辈乱精品视频 | 欧州一区二区 | 国产一级一片免费播放 | 久久成人精品一区二区 | 美女上床网站 | 欧美午夜小视频 | 夜色伊人 | 日美一级片 | 久久这里只有精品99 | 久久久综合网 | 一区二区三区天堂 | 轮番上阵免费观看在线电影 | 熟女人妇 成熟妇女系列视频 | 国产精品久久久久高潮 | 中文字幕一区二区三区手机版 | 日韩福利一区二区三区 | 国产精品久久久久久久久免费 | aa丁香综合激情 | 打屁股黄文 | 99久久综合国产精品二区 | 与子敌伦刺激对白播放的优点 | 一区二区三区欧美在线 | 91网站视频在线观看 | 欧美成人免费在线观看 | 人妻av无码一区二区三区 | 午夜福利电影一区二区 | 成人三级视频 | 国模一区二区三区 | 五月婷婷丁香六月 | 欧美久久久久久又粗又大 | 少妇真人直播免费视频 | 国产56页| 国产精品免费视频一区二区三区 | 精品黄色 | 午夜污污| 中文字幕人妻一区二区在线视频 | 白白色免费视频 | 久久超碰精品 | 美女黄色一级 | 欧美性一区 | 亚洲一区二区黄片 | 99re热这里只有精品视频 | 国产成人 综合 亚洲 | 欧美一级大片在线观看 | 波多野结衣精品视频 | 无码一区二区三区 | 亚洲中文字幕在线观看 | 亚洲一区二区三 | 成人午夜网| 欧美黄色片视频 | 亚洲成av人片一区二区 | 国产麻豆一区二区三区在线观看 | 中文字幕第6页 | 中文字幕第页 | 99免费国产 | 欧美精品色 | 久久成人一区 | 黄色片日韩| 麻豆91视频|