Linux系統編程—共享內存之mmap

共享內存概念

共享內存是通信效率最高的IPC方式,因為進程可以直接讀寫內存,而無需進行數據的拷備。但是它沒有自帶同步機制,需要配合信號量等方式來進行同步。

共享內存被創建以後,同一塊物理內存被映射到了多個進程地址空間,當有一個進程修改了共享內存的數據,其餘的進程均可看見所修改的內容,反之亦然。

Linux系統編程—共享內存之mmap

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去釋放。

例程

寫進程:

<code> 1#include 
 2#include 
 3#include 
 4#include 
 5#include 
 6#include 
 7#include 
 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}
/<code>

讀進程:

<code> 1#include 
 2#include 
 3#include 
 4#include 
 5#include 
 6#include 
 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}
/<code>

> 2020 精選 阿里/騰訊等一線大廠 面試、簡歷、進階、電子書 「**良許Linux**」後臺回覆「**資料**」免費獲取

#### 看完的都是真愛,點個贊再走唄?您的「三連」就是良許持續創作的最大動力!

1. 關注**原創**「**良許Linux**」,第一時間獲取最新Linux乾貨!

2. 後臺回覆【資料】【面試】【簡歷】獲取精選一線大廠面試、自我提升、簡歷等資料。

3. 關注我的博客:[lxlinux.net](http://www.lxlinux.net)


分享到:


相關文章: