内存控制函数(1)-mmap() 建立内存映射

示例1:

1.首先建立一个文本文件,名字为tmp,内容为hello world

2.编写mmap.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>

int main()
{
        int fd, len;
        int *p; 
        fd = open("tmp", O_RDWR);
        if (fd < 0) {
                perror("open");
                exit(1);
        }
    
        len = lseek(fd, 0, SEEK_END);
        // 第一个参数代表内存起始地址,设为NULL代表让系统自动选定地址
        p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
        if (p == MAP_FAILED) {
                perror("mmap");
                exit(1);
        }
        // 如果映射成功,修改p[0]
        p[0] = 0x30313233;
        close(fd);
        // 释放内存映射地址
        munmap(p, len);
        return 0;
}

3.运行,并查看tmp内容

od -tx1 -tc tmp

0000000 33 32 31 30 6f 20 77 6f 72 6c 64 0a
3 2 1 0 o w o r l d \n
0000014

磁盘文件tmp的内容已被修改.

 

示例2:利用mmap实现进程间通信

process_mmap_w.c

/* process_mmap_w.c */
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

#define MAPLEN 0X1000

struct STU {
    int id;
    char name[20];
    char sex;
};

void sys_error(char *str, int exitno)
{
    perror(str);
    exit(exitno);
}


int main(int argc, char *argv[])
{
    
    struct STU *mm;
    int fd, i = 0;
    if(argc < 2) {
        printf("Need filename! \n");
        exit(1);
    }
         fd = open(argv[1], O_RDWR | O_CREAT, 0777);        
    if (fd < 0)
        sys_error("open", 1);
        
    if (lseek(fd, MAPLEN-1, SEEK_SET) < 0)
        sys_error("lseek", 3);
    
    if (write(fd, "\0", 1) < 0)
        sys_error("write", 4);
    
    mm = mmap(NULL, MAPLEN, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    if (mm == MAP_FAILED)
        sys_error("mmap", 2);

    close(fd);
    
    while(1) {
        mm->id = i;
        sprintf(mm->name, "zhang-%d", i);
        if (i%2 == 0)
            mm->sex = 'm';
        else
            mm->sex = 'w';
        i++;
        sleep(1);            
    }
    munmap(mm, MAPLEN);
    return 0;
}

process_mmap_r.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

#define MAPLEN 0x1000

struct STU {
    int id;
    char name[20];
    char sex;
};

void sys_err(char *str, int exitno)
{
    perror(str);
    exit(exitno);
}

int main(int argc, char *argv[])
{
    int fd;    
    struct STU *mm;    

    if (argc < 2) {
        printf("Need input filename\n");
        exit(1);
    }

    fd = open(argv[1], O_RDWR);
    if (fd < 0)
        sys_err("open", 1);
    
    mm = mmap(NULL, MAPLEN, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    if (mm == MAP_FAILED)
        sys_err("mmap", 2);
    
    close(fd);
    
    unlink(argv[1]);
    
    while(1) {
        printf("%d\n", mm->id);
        printf("%s\n", mm->name);
        printf("%c\n", mm->sex);
        sleep(1);
    }
    munmap(mm, MAPLEN);
    return 0;
}

运行两个进程:

10
zhang-10
m
11
zhang-11
w
12
zhang-12
m
13
zhang-13
w
14
zhang-14
m

 

posted @ 2017-12-18 23:11  夜行过客  阅读(281)  评论(0编辑  收藏  举报