mmap Linux process communication of

mmap () function:

void *mmap(void* addr,size_t length,int port,int flags,int fd,off_t offset);

Returns: Success: returns the first address mapping area created; failure: MAP_FAILED Macro

parameter:

       addr: the establishment of the first address mapping area, determined by the linux kernel. When used directly pass NULL;

       length: To create the size of the map area

       port: mapping area authority PROT _READ, PROT_WRITE, PROT _READ | PROTWRITE

       flags: Flag parameter (often used to set the update physical area, set the share, create an anonymous mapping area)

                     MAP_SHARED: Operation will be made to the physical mapping area reflecting device

                     MAP_PRIVATE: modify the mapping area made will not be reflected to the physical device.

       fd: file descriptor used to build the mapping area

       offset: offset map file (4K integer multiple)

/***
mmap.c
***/
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/mman.h>

int main()
{
    int len,ret;
    char *p = NULL;
    int fd = open("mytest.txt",O_CREAT|O_RDWR,0644);
    if(fd < 0 )
    {
        perror("open error:");
        exit(1);
    }
    len = ftruncate(fd,4);
    if(-1 == len)
    {
        perror("ftruncate  error:");
        exit(1);
    }
    p = mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    if(p == MAP_FAILED)
    {
        perror("mmap error:");
        exit(1);
    }
    strcpy(p,"abc");

    ret = munmap(p,4);
    if(-1 == ret)
    {
        perror("mmap error:");
        exit(1);
    } 
    close(fd);
    return 0;
}

operation result:

ubuntu1604 personality @: ~ / wangqinghe / linux / 20190807 $ gcc mmap.c -that Map

ubuntu1604@ubuntu:~/wangqinghe/linux/20190807$ ./mmap

ubuntu1604@ubuntu:~/wangqinghe/linux/20190807$ cat mytest.txt

abc

mmap note the following during use:

  1. The process of creating a mapping zone, implies a read operation on the mapping file.
  2. When MAP_SHARED, it is required: Permission mapping area of ​​<= permission to open files (for the protection of mapped areas). The MAP_PRIVATE then it does not matter, because the time limit for memory mmap of authority.
  3. Release and file mapping area closed unrelated. As long as the mapping is successful, the file can be closed immediately.
  4. Special Note: When mapping file size is zero, you can not create a mapping area. So: there must be mapped file for the actual size. Often bus error occurs when mmap use, usually because the shared file storage space caused.
  5. munmap incoming address must be mmap return address, and resolutely put an end to the operation pointer ++
  6. If a file offset, then the value must be an integer multiple of 4K
  7. mmap creates a mapping error high probability area, be sure to check the return value to ensure the success of re-mapping area to establish follow-up action.

 

mmap-process communication between father and son:

Inode file attributes

struct stat

{

       Memory pointer address;

       size;

       Authority;

       Types of;

       So who;

}

/***
mmap_fork.c
***/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<sys/wait.h>

int var = 100;

int main()
{
    int *p;
    pid_t pid;
    
    int fd;
    fd = open("temp",O_RDWR|O_CREAT|O_TRUNC,0644);
    if(fd < 0)
    {
        perror("open error");
        exit(1);
    }
    unlink("temp");
    ftruncate(fd,4);
    
    p = (int*)mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    if(p == MAP_FAILED)
    {
        perror("mmap error");
        exit(1);
    }
    close(fd);

    pid = fork();
    if(0 == pid)
    {
        *p = 2000;
        var = 1000;
        printf("child, *p = %d, var = %d\n",*p,var);
    }
    else
    {
        sleep(1);
        printf("parent, *p = %d, var = %d\n",*p,var);
        wait(NULL);
        
        int ret = munmap(p,4);
        if(-1 == ret)
        {
            perror("munmap error");
            exit(1);
        }
    }
    return 0;
}

operation result:

ubuntu1604@ubuntu:~/wangqinghe/linux/20190807$ gcc mmap_fork.c -o mmap_fork

ubuntu1604@ubuntu:~/wangqinghe/linux/20190807$ ./mmap_fork

child, *p = 2000, var = 1000

parent, *p = 2000, var = 100

 

create anonymous mmap mapped area

/***
fork_mmap_linux.c
***/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<sys/wait.h>

int var = 100;

int main()
{
    int *p;
    pid_t pid;
    
    p = (int*)mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED | MAP_ANON,-1,0);
    if(p == MAP_FAILED)
    {
        perror("mmap error");
        exit(1);
    }

    pid = fork();
    if(0 == pid)
    {
        var = 1000;
        *p = 2000;
        printf("child, *p = %d,var = %d\n",*p,var);
    }
    else
    {
        sleep(1);
    //    printf("parent,*p = %d\n",*p);
        printf("child, *p = %d,var = %d\n",*p,var);
        wait(NULL);
        int ret = munmap(p,4);
        if(-1 == ret)
        {
            perror("munmap error");
            exit(1);
        }
    }
    return 0;
}

operation result:

ubuntu1604@ubuntu:~/wangqinghe/linux/20190807$ gcc fork_map_linux.c -o fork_map_linux

ubuntu1604 @ ubuntu: ~ / wangqinghe / linux / 20190807 $ ./fork_map_linux

child, *p = 2000,var = 1000

child, *p = 2000,var = 100

 

Note: MAP_ANONYMOUS MAP_ANON two macros and linux operating system specific macros, then Unix-based systems without the macro definition, the following steps may be used to complete the establishment of the anonymous mapping area.

  1. fd = open(“/dev/zero”,O_RDWR);
  2. p = mmap(NULL,size,PROT_READ|PROT_WRITE,MMAP_SHARED,fd,0);
/***
fork_map_anon.c
***/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<sys/wait.h>

int var = 100;

int main()
{
    int *p;
    pid_t pid;
    int fd = open("/dev/zero",O_RDWR);
    
    p = (int*)mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    if(p == MAP_FAILED)
    {
        perror("mmap error");
        exit(1);
    }

    pid = fork();
    if(0 == pid)
    {
        var = 1000;
        *p = 2000;
        printf("child, *p = %d,var = %d\n",*p,var);
    }
    else
    {
        sleep(1);
    //    printf("parent,*p = %d\n",*p);
        printf("child, *p = %d,var = %d\n",*p,var);
        wait(NULL);
        int ret = munmap(p,4);
        if(-1 == ret)
        {
            perror("munmap error");
            exit(1);
        }
    }
    return 0;
}

operation result:

buntu1604@ubuntu:~/wangqinghe/linux/20190807$ gcc fork_map.c -o fork_map

ubuntu1604@ubuntu:~/wangqinghe/linux/20190807$ ./fork_map

child, *p = 2000,var = 1000

child, *p = 2000,var = 100

 

mmap no blood relationship between the process of communication:

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

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

void sys_err(char *str)
{
    perror(str);
    exit(1);
}

int main(int argc,char ** argv)
{
    int fd;
    struct STU student = {10,"xiaoming",'m'};
    char *mm;
    
    if(argc < 2)
    {
        printf("./a.out file_shared\n");
        exit(-1);
    }

    fd = open(argv[1],O_RDWR | O_CREAT,0664);
    ftruncate(fd,sizeof(student));
    
    mm = mmap(NULL,sizeof(student),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    if(mm == MAP_FAILED)
    {
        sys_err("mmap error");
    }

    close(fd);

    while(1)
    {
        memcpy(mm,&student,sizeof(student));
        student.id++;
        sleep(2);
    }

    munmap(mm,sizeof(student));
    return 0;
}
/***
mmap_r.c
***/
#include<stdio.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/mman.h>
#include<string.h>

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

void sys_err(char *str)
{
    perror(str);
    exit(1);
}

int main(int argc,char ** argv)
{
    int fd;
    struct STU student;
    struct STU *mm;
    
    if(argc < 2)
    {
        printf("./a.out file_shared\n");
        exit(-1);
    }

    fd = open(argv[1],O_RDONLY);
    if(-1 == fd)
        sys_err("open error");
    
    mm = mmap(NULL,sizeof(student),PROT_READ,MAP_SHARED,fd,0);
    if(mm == MAP_FAILED)
    {
        sys_err("mmap error");
    }

    close(fd);

    while(1)
    {
        printf("id=%d,name = %s,%c\n",mm->id,mm->name,mm->sex);
        sleep(2);
    }

    munmap(mm,sizeof(student));
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/wanghao-boke/p/11317614.html