测试mmap

版权声明: https://blog.csdn.net/dashoumeixi/article/details/83866049

mmap  参数 :

addr : 依据边界颗粒度 (提升到某个页面的整数倍)

length , offset : 总是某个页面的整数倍 

页面大小 : sysconf(_SC_PAGE_SIZE); 一般 4096 或 8192

基础:

如果映射大小超过了文件大小 , 则在映射区写入的字节将被丢弃

以下例子 可使用 od -b -A d 1.dat 来查看写入情况

    int fd = open("1.dat",O_RDWR|O_CREAT|O_TRUNC,0777);

    ftruncate(fd,5000);

    //这里是 4096 字节
    int pagesize = sysconf(_SC_PAGE_SIZE);
    printf("pagesize : %d\n", pagesize);

    //1024 被提升到 4096 字节.
    char *p = (char*)mmap(NULL,1024,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

    p[pagesize - 1] = 1;
    printf("p[%d] = %d\n" , pagesize,p[pagesize - 1]);

    //p[pagesize] = 1; //出错 . 超出了映射范围
    
    int fd = open("1.dat",O_RDWR|O_CREAT|O_TRUNC,0777);

    ftruncate(fd,5000);

    //这里是 4096 字节
    int pagesize = sysconf(_SC_PAGE_SIZE);
    printf("pagesize : %d\n", pagesize);

    //5000 被提升 8192 字节
    char *p = (char*)mmap(NULL,5000,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

    p[pagesize - 1] = 1;
    printf("p[%d] = %d\n" , pagesize,p[pagesize - 1]);

    //文件大小 5000 , 而映射区有8192,超出文件大小的映射区可读写,但不会写入文件
    p[8191] = 1;
    printf("p[%d] = %d\n" , 8191,p[8191]);
    int fd = open("1.dat",O_RDWR|O_CREAT|O_TRUNC,0777);

    ftruncate(fd,5000);

    //这里是 4096 字节
    int pagesize = sysconf(_SC_PAGE_SIZE);
    printf("pagesize : %d\n", pagesize);

    //映射 20000 个字节 , 但实际映射成8192字节
    char *p = (char*)mmap(NULL,20000,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

    //出错了 。 一旦映射大小 超过了文件本身,将以文件大小提升成页面整数
    p[8192] = 1;
    printf("p[%d] = %d\n" , 8192,p[8192]);

1. 基于有名信号量

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

int main(int argc , char ** argv , char ** env)
{
   int zero = 0 , times = 10;
   int fd = open("1.dat",O_RDWR|O_CREAT,0777);
   write(fd,&zero,sizeof(int));

  //addr : 边界颗粒度 . length , offet : 页面的倍数
  //MAP_SHARED : 所做的操作都直接写入硬盘
   int *ptr = mmap(NULL,sizeof(int),PROT_WRITE|PROT_READ,
   MAP_SHARED,fd,0);
   sem_t * sem = sem_open("/testsem",O_CREAT|O_EXCL,0777,1);
   sem_unlink("testsem");
   close(fd);
   setbuf(stdout,NULL);
   if(0 == fork()){
       for(int i = 0 ; i < times; ++i){
           sem_wait(sem);
           printf("child count:%d\n" , (*ptr)++);
           sem_post(sem);
       }
       return 0;
   }
   for(int i = 0 ; i< times;++i){
       sem_wait(sem);
       printf("parent count:%d\n" , (*ptr)++);
       sem_post(sem);
   }


    return 0;
}

2.基于内存信号量:

struct shareobject{
    sem_t sem;
    int count;
} shared;


int main()
{
    int times = 10;
    int fd = open("1.dat",O_RDWR|O_CREAT,0777);
    write(fd,&shared,sizeof(shared));

    /*
        把内存信号量写入文件,通过mmap 映射后,
        相当于一个共享内存. 
        在共享内存里读写
    */

    struct shareobject * p = (struct shareobject *)mmap(NULL,sizeof(shared),PROT_WRITE|PROT_READ,MAP_SHARED,
    fd,0);
    sem_init(&p->sem,1,1);

    if(0 == fork()){
        for(int i = 0 ; i < times ; ++i){
            sem_wait(&p->sem);
            printf("child count : %d\n" , p->count++);
            sem_post(&p->sem);
        }
        return 0;
    }

    for(int i =0 ; i< times; ++i){
        sem_wait(&p->sem);
        printf("parent count : %d\n" , p->count++);
        sem_post(&p->sem);
    }


    close(fd);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/dashoumeixi/article/details/83866049
今日推荐