共享記憶體概念
共享記憶體是通訊效率最高的IPC方式,因為程式可以直接讀寫記憶體,而無需進行資料的拷備。但是它沒有自帶同步機制,需要配合訊號量等方式來進行同步。
共享記憶體被建立以後,同一塊實體記憶體被對映到了多個程式地址空間,當有一個程式修改了共享記憶體的資料,其餘的程式均可看見所修改的內容,反之亦然。
mmap函式
函式原型:
void *mmap(void *adrr, size_t length, int prot, int flags, int fd, off_t offset);
返回值:
成功:返回建立的對映區首地址;
失敗:返回MAP_FAILED
具體引數含義:
addr:指向對映區的首地址,這是由系統核心所決定的,一般設為NULL;
length:欲建立的對映區大小;
prot:對映區的許可權,一般有如下幾種:
PROT_EXEC 對映區域可被執行
PROT_READ 對映區域可被讀取
PROT_WRITE 對映區域可被寫入
PROT_NONE 對映區域不能存取
flags:指對映區的標誌位,MAP_FIXED與MAP_PRIVATE必須選擇一個:
MAP_FIXED:對對映區所作的修改會反映到物理裝置,但需要呼叫msync()或者munmap();
MAP_PRIVATE:對對映區所作的修改不會反映到物理裝置。
fd:建立的對映區的檔案描述符;
offset:被對映檔案的偏移量,一般設為0,表示從頭開始對映。
mumap函式
函式原型:
int munmap(void *addr, size_t length);
函式作用:
如同malloc之後需要free一樣,mmap呼叫建立的對映區使用完畢之後,需要呼叫munmap去釋放。
例程
寫程式:
1#include <stdio.h>
2#include <sys/mman.h>
3#include <sys/types.h>
4#include <sys/stat.h>
5#include <fcntl.h>
6#include <unistd.h>
7#include <string.h>
8
9typedef struct
10{
11 int id;
12 char name[20];
13 char gender;
14}stu;
15
16int main(int argc, char *argv[])
17{
18 stu *p = NULL;
19 int fd = 0;
20 stu student = {10, "harry", 'm'};
21
22 if (argc < 2) {
23 printf("useage: ./a.out file\n");
24 return -1;
25 }
26
27 fd = open(argv[1], O_RDWR | O_CREAT, 0664);
28 if (fd == -1) {
29 printf("ERROR: open failed!\n");
30 return -1;
31 }
32 ftruncate(fd, sizeof(stu));
33
34 p = mmap(NULL, sizeof(stu), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
35 if (p == MAP_FAILED) {
36 printf("ERROR: mmap failed!\n");
37 return -1;
38 }
39
40 close(fd);
41
42 while (1) {
43 memcpy(p, &student, sizeof(stu));
44 student.id++;
45 sleep(2);
46 }
47 munmap(p, sizeof(stu));
48
49 return 0;
50}
複製程式碼
讀程式:
1#include <stdio.h>
2#include <sys/mman.h>
3#include <sys/types.h>
4#include <sys/stat.h>
5#include <fcntl.h>
6#include <unistd.h>
7
8typedef struct
9{
10 int id;
11 char name[20];
12 char gender;
13}stu;
14
15int main(int argc, char *argv[])
16{
17 stu *p = NULL;
18 int fd = 0;
19
20 if (argc < 2) {
21 printf("useage: ./a.out file\n");
22 return -1;
23 }
24
25 fd = open(argv[1], O_RDONLY);
26 if (fd == -1) {
27 printf("ERROR: open failed!\n");
28 return -1;
29 }
30
31 p = mmap(NULL, sizeof(stu), PROT_READ, MAP_SHARED, fd, 0);
32 if (p == MAP_FAILED) {
33 printf("ERROR: mmap failed!\n");
34 return -1;
35 }
36
37 close(fd);
38
39 while (1) {
40 printf("id = %d, name = %s, gender = %c\n", p->id, p->name, p->gender);
41 sleep(2);
42 }
43
44 munmap(p, sizeof(stu));
45
46 return 0;
47}
複製程式碼
更多精彩內容,請關注公眾號良許Linux,公眾內回覆1024可免費獲得5T技術資料,包括:Linux,C/C++,Python,樹莓派,嵌入式,Java,人工智慧,等等。公眾號內回覆進群,邀請您進高手如雲技術交流群。