分享

Linux系统编程 | 共享内存之mmap

 西北望msm66g9f 2018-07-20

 



作者

良许

一个热爱技术的程序猿


共享内存概念


共享内存是通信效率最高的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 
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(NULLsizeof(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 
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(NULLsizeof(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}


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多