linux共享内存之mmap

来源:互联网 发布:python pack 编辑:程序博客网 时间:2024/04/27 14:49

这应该可以算得上是IPC的一种,虽然效率可能并没有其它IPC方式高.

看到map很容易联想到映射.的确,mmap就是一种映射方式,将打开的文件和一段连续的内存做映射.使得对内存进行操作即可以实现对文件的读写,反过来,也就是说,可以通过这种方式来达到进程通信.

mmap系列涉及三个函数.

void * mmap(void *buf, size_t len, int prot, int flag, int fd, off_t offset);

此函数建立一个共享内存,prot即为权限,可选值有PROT_READ, PROT_WRITE, PROT_EXEC, PROT_NONE.顾名思义,就不多说了.

flag即为共享内存作用范围.部分可取值为MAP_SHARED(进程共享,即当做出了修改,会写回到文件), MAP_PRIVATE(私有,即不会影响到文件), MAP_FIXED(一般情况下,buf参数置为NULL,由系统来分配地址,但是如果指定了这个字段,buf不能为空,否则core dump).

int msync(void *buf, size_t len, int flags);

此函数同步共享内存与文件的值,flags可取如下值,MS_ASYNC(同步), MS_SYNC(异步), MS_INVALIDATE(从文件中读回数据).

munmap(void* buf, size_t len);

此函数关闭共享内存.


使用这些常用的选项写一个简单的小程序.

#include <unistd.h>#include <sys/types.h>#include <stdio.h>#include <sys/mman.h>#include <fcntl.h>typedef struct {    int integer;    char string[24];}RECORD;#define NRECORD 5int main(int argc, char ** argv){    RECORD *mapped;    int i, f;        f = open("record.dat", O_RDWR);    mapped = (RECORD*)mmap(0, sizeof(RECORD) * NRECORD, PROT_READ | PROT_WRITE, MAP_SHARED, f, 0);    printf("********************first of all***********************\n");    for (i = 0; i < NRECORD; i++)    {        printf("record (%d) is %s\n", (mapped + i)->integer, (mapped + i)->string);        (mapped + i)->integer += 100;        snprintf((mapped + i)->string, 24, "RECORD-%d", (mapped + i)->integer);    }    msync((void *)mapped, sizeof(RECORD) * NRECORD, MS_INVALIDATE);   //MS_INVALIDATE MS_ASYNC MS_SYNC 这三个宏都可以达到更新文件的效果.不晓得三者的区别.    printf("********************second of all***********************\n");    for (i = 0; i < NRECORD; i++)    {        printf("record (%d) is %s\n", (mapped + i)->integer, (mapped + i)->string);        (mapped + i)->integer += 100;        snprintf((mapped + i)->string, 24, "RECORD-%d", (mapped + i)->integer);    }    msync((void*)mapped, sizeof(RECORD) * NRECORD, MS_ASYNC);    printf("********************third of all***********************\n");    for (i = 0; i < NRECORD; i++)    {        printf("record (%d) is %s\n", (mapped + i)->integer, (mapped + i)->string);        (mapped + i)->integer += 100;        snprintf((mapped + i)->string, 24, "RECORD-%d", (mapped + i)->integer);    }    munmap((void*)mapped, sizeof(RECORD) * NRECORD);    return 0;}

这三个函数在对文件进行操作的时候,其实优点还是很明显的.但是说到用来共享内存,相信这绝对不是一个好的选择.

0 0
原创粉丝点击