mmap

  mmap的作用是将磁盘文件的数据映射到内存,用户通过修改内存就能修改磁盘文件。

 

1.函数原型:void *mmap(void *addr,size_t length,int prot,int flags,int fd,off_t offset);

  addr:映射区的首地址,可以传NULL

  length:映射区的大小,一般为4k的倍数。如传100,大小也为4k。一般传入文件的大小

  prot:映射区权限。权限有读权限(必须)PROT_READ,写权限(可选)PROT_WRITE

  flags:标志位参数。MAP_SHARED,修改了内存后,数据会同步到磁盘;

           MAP_PRIVATE,修改了内存后,数据不会同步到磁盘。

  fd:将要映射的文件的文件描述符

  offset:映射文件的偏移量,必须是4k的整数倍,一般传0

 

2.返回值:成功:返回映射区首地址

     失败:返回一个宏MAP_FAILED

 

3.munmap

释放内存映射区

函数原型:int munmap(void *addr,size_t length);

  addr:mmap的返回值,映射区首地址

  length:mmap的第二个参数,映射区长度

 

mmap的使用

 1 #include <sys/mman.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <fcntl.h>
 5 #include <unistd.h>
 6 
 7 int main()
 8 {
 9         int fd = open("chinese.txt",O_RDWR);
10         if(fd == -1){
11                 perror("open error:");
12                 exit(-1);
13         }
14         int len = lseek(fd,0,SEEK_END);
15         printf("file size is %d\n",len);
16         char *ptr = (char *)mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);
17 
18         if(ptr==MAP_FAILED){
19                 perror("mmap error:");
20                 exit(-1);
21         }
22         printf("%s\n",ptr);
23 
24         munmap(ptr,len);
25         close(fd);
26         return 0;
27 }

  

 4.进程间通信

有血缘关系的进程之间:父子进程共享内存映射区(有名映射区)

 1 #include <sys/mman.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <fcntl.h>
 5 #include <unistd.h>
 6 #include <sys/wait.h>
 7 #include <string.h>
 8 
 9 int main()
10 {
11         int fd = open("chinese.txt",O_RDWR);
12         if(fd == -1){
13                 perror("open error:");
14                 exit(-1);
15         }
16         int len = lseek(fd,0,SEEK_END);
17         printf("file size is %d\n",len);
18         char *ptr = (char *)mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);
19 
20         if(ptr==MAP_FAILED){
21                 perror("mmap error:");
22                 exit(-1);
23         }
24 //      printf("%s\n",ptr);
25 
26         pid_t pid = fork();
27         if(pid == -1){
28                 perror("fork error:");
29                 exit(-1);
30         }
31 
32         if(pid > 0){
33                 strcpy(ptr,"你是我儿吗");
34                 wait(NULL);
35         }else if(pid == 0){
36                 printf("%s\n",ptr);
37         }
38 
39         munmap(ptr,len);
40         close(fd);
41         return 0;
42 }

 

匿名映射区

 

#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>

int main()
{
        int len = 4096;
        char *ptr = (char *)mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0);

        if(ptr==MAP_FAILED){
                perror("mmap error:");
                exit(-1);
        }
//      printf("%s\n",ptr);

        pid_t pid = fork();
        if(pid == -1){
                perror("fork error:");
                exit(-1);
        }

        if(pid > 0){
                strcpy(ptr,"你是我儿吗");
                wait(NULL);
        }else if(pid == 0){
                printf("%s\n",ptr);
        }

        munmap(ptr,len);
        return 0;
}

 

 

没有血缘关系的进程之间:不能借助匿名映射区的方式,只能借助磁盘文件映射的方式

写端:

 

 1 #include <sys/mman.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <fcntl.h>
 5 #include <unistd.h>
 6 #include <sys/wait.h>
 7 #include <string.h>
 8 
 9 int main()
10 {
11         int fd = open("temp",O_RDWR|O_CREAT,0664);
12         if(fd == -1){
13                 perror("open error:");
14                 exit(-1);
15         }
16 
17         int len = lseek(fd,0,SEEK_END);
18         char *ptr = (char *)mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);
19 
20         if(ptr==MAP_FAILED){
21                 perror("mmap error:");
22                 exit(-1);
23         }
24 //      printf("%s\n",ptr);
25 
26         while(1){
27                 sleep(2);
28                 char *ptemp = ptr+1024;
29                 strcpy(ptemp,"你是我儿吗\n");
30         }
31 
32         close(fd);
33         munmap(ptr,len);
34         return 0;
35 }

 

读端:

 1 #include <sys/mman.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <fcntl.h>
 5 #include <unistd.h>
 6 #include <sys/wait.h>
 7 #include <string.h>
 8 
 9 int main()
10 {
11         int fd = open("temp",O_RDWR|O_CREAT,0664);
12         if(fd == -1){
13                 perror("open error:");
14                 exit(-1);
15         }
16 
17         ftruncate(fd,4096);     //文件大小拓展
18         int len = lseek(fd,0,SEEK_END);
19         char *ptr = (char *)mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);
20 
21         if(ptr==MAP_FAILED){
22                 perror("mmap error:");
23                 exit(-1);
24         }
25 //      printf("%s\n",ptr);
26 
27         while(1){
28                 sleep(1);
29                 printf("%s\n",ptr+1024);
30         }
31 
32         close(fd);
33         munmap(ptr,len);
34         return 0;
35 }

 

5.创建匿名映射区的方法

mmap函数参数的改变:

  第二个参数:改为要指定的映射区的大小,原来为文件的大小

  第四个参数:需要添加MAP_ANON宏

  第五个参数:-1,原来为fd

 

posted @ 2021-02-18 13:39  さくらむすび  阅读(65)  评论(0)    收藏  举报