我是靠谱客的博主 等待马里奥,这篇文章主要介绍mmap函数mmap函数匿名映射:,现在分享给大家,希望可以做个参考。

mmap函数

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
1.创建映射区 void *mmap(void *adrr,size_t length,int prot,int flags,int fp,off_t offset); addr:建立映射区的首地址,直接传NULL length:映射区的大小 prot:映射区权限PROT_READ,PROT_WRITE,PROT_READ|PROT_WRITE flags:标志位参数,MAP_SHARED将映射区所做的操作反映到物流设备(磁盘)上(父子进程可以共享映射区) MAP_PRIVATE不反映(父子进程不共享映射区,各自独占)。 offset:映射文件的偏移(4k的整数倍)为0时表示起始位置。 成功:返回映射区的首地址,失败:返回MAP_FAILED
  • 新建立的文件不能创建映射区,也就是说,不能创建大小为0的映射区
  • 可以在堆区开辟大小为0的空间(void *malloc(unsigned int size));
  • 映射区的权限要 <= 打开文件的权限
  • 映射区创建的过程中隐含一次对文件的读操作
  • 父子进程共享mmap建立的映射区,和打开的文件
  • 当mmap中的flags参数设置成MAP_PRIVATE时,父子进程各自独占映射区,不共享。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
2.关闭映射区 int munmap(void *addr,size_t length); ```c #include<stdio.h> #include<fcntl.h> #include<unistd.h> #include<stdlib.h> #include<sys/mman.h> #include<string.h> int main() { int fp = open("test",O_RDWR | O_CREAT,0644); if(fp == -1) { perror("open error:"); exit(1); } int file_len = truncate("test",1024); if(file_len == -1) { perror("truncate error"); exit(1); } char *mp = NULL; mp = mmap(NULL,1024,PROT_READ | PROT_WRITE,MAP_SHARED,fp,0); if(mp == MAP_FAILED) { perror("mmap error:"); exit(1); } else { strcpy(mp,"6666666666666666666n"); int nump = munmap(mp,1024); if(nump == -1) { perror("munmap error:"); exit(1); } close(fp); } return 0; }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<fcntl.h> #include<sys/mman.h> #include<sys/wait.h> int variety = 666; int main() { int fp = open("test",O_RDWR | O_CREAT | O_TRUNC,0644); if(fp == -1) { perror("open error:"); exit(1); } ftruncate(fp,512); int len = lseek(fp,0,SEEK_END); printf("the length of test is:%dn",len); int *mp; mp = mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_SHARED,fp,0); if(mp == MAP_FAILED) { perror("mmap error:"); exit(1); } close(fp); int ul = unlink("test"); if(ul == 0) { printf("file is deleted successfuln"); } pid_t pid = fork(); if(pid == 0) { printf("I am childn"); *mp = 999; variety = 888; printf("*mp = %d,variety = %dn",*mp,variety); } else { sleep(1); printf("I am fathern"); printf("*mp = %d,variety = %dn",*mp,variety); wait(NULL); } int numap = munmap(mp,len); if(numap == -1) { perror("numap error:"); exit(1); } return 0; }

匿名映射:

复制代码
1
2
3
4
5
6
- 无需依赖一个文件即可建立映射区 - 在参数flags中加入:MAP_ANONYMOUS(ANON) ```cpp int*p=mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,O);
  • 需注意的是,MAP_ANONYMOUS和MAP_ANON这两个宏是Linux操作系统特有的宏。在类Unix系统中如无宏定义,可使用如下两步来完成匿名映射区的建立。
复制代码
1
2
3
int fd=open("/dev/zero",O_RDWR); p=mmap(NULL,size,PROT_READ|PROT_WRITE,MMAP_SHARED,fd,0);
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<fcntl.h> #include<sys/mman.h> #include<sys/wait.h> int variety = 666; int main() { int *mp; mp = mmap(NULL,128,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANON,-1,0); if(mp == MAP_FAILED) { perror("mmap error:"); exit(1); } pid_t pid = fork(); if(pid == 0) { printf("I am childn"); *mp = 999; variety = 888; printf("*mp = %d,variety = %dn",*mp,variety); } else { sleep(1); printf("I am fathern"); printf("*mp = %d,variety = %dn",*mp,variety); wait(NULL); } int numap = munmap(mp,128); if(numap == -1) { perror("numap error:"); exit(1); } return 0; }

总结:使用mmap时务必注意以下事项:

1.创建映射区的过程中,隐含着一次对映射文件的读操作。
2.当MAP_SHARED时,要求:映射区的权限应<=文件打开的权限(出于对映射区的保护)。而MAP_PRIVATE则无所谓,因为mmapf的权限是对内存的限制。
3.映射区的释放与文件关闭无关。只要映射建立成功,文件可以立即关闭。
4.特别注意,当映射文件大小为0时,不能创建映射区。所以:用于映射的文件必须要有实际大小!mmap.使用时常常会出现总线错误,通常是由于共享文件存储空间大小引起的。
5.munmap.传入的地址一定是mmap的返回地址。坚决杜绝指针++/- -操作。
6.offset文件偏移量必须为4K的整数倍
7.mmap创建映射区出错概率非常高,一定要检查返回值,确保映射区建立成功再进行后续操作。
8.因为创建mmap函数比较容易出错,所以创建完成后一定要通过判断返回值来确定是否创建成功

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
将结构体写入文件中 #include<sys/mman.h> #include<sys/wait.h> #include<string.h> #include<sys/types.h> #include<sys/stat.h> struct stu{ int num; char name[16]; int class; }; int main(int argc,char *argv[]) { struct stu student = {1,"zjl",11}; if (argc<2) { printf("argument is lessn"); exit(1); } int fp = open(argv[1],O_RDWR | O_CREAT | O_TRUNC,0644); int len = sizeof(student); printf("student len is:%dn",len); ftruncate(fp,128); int length = lseek(fp,0,SEEK_END); printf("the len of fp is:%dn",length); int *mp = mmap(NULL,len,PROT_WRITE | PROT_READ,MAP_SHARED,fp,0); if(mp == MAP_FAILED) { perror("mmap error:"); exit(1); } close(fp); while(1) { printf("enter while len is:%dn",len); printf("student.name = %sn",student.name); memcpy(mp,&student,64); student.num++; sleep(1); } int numap = munmap(mp,128); if(numap == -1) { perror("numap error:"); exit(1); } return 0; }

2个不相关进程间的通信

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
先写入shared_file文件中 #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<fcntl.h> #include<sys/mman.h> #include<sys/wait.h> #include<string.h> #include<sys/types.h> #include<sys/stat.h> struct stu{ int num; char name[16]; int class; }; int main(int argc,char *argv[]) { struct stu student = {1,"zjl",11}; int fp = open("sharerd_file",O_RDWR | O_CREAT | O_TRUNC,0644); int len = sizeof(student); printf("student len is:%dn",len); ftruncate(fp,128); int *mp = mmap(NULL,len,PROT_WRITE | PROT_READ,MAP_SHARED,fp,0); if(mp == MAP_FAILED) { perror("mmap error:"); exit(1); } close(fp); printf("start to write!!!n"); int n = 0; while(1) { n += 1; printf("[%d]writen",n); memcpy(mp,&student,64); student.num++; student.class++; sleep(1); } int numap = munmap(mp,128); if(numap == -1) { perror("numap error:"); exit(1); } return 0; }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
再从文件中读出 #include<unistd.h> #include<fcntl.h> #include<sys/mman.h> #include<sys/wait.h> #include<string.h> #include<sys/types.h> #include<sys/stat.h> struct stu{ int num; char name[16]; int class; }; int main(int argc,char *argv[]) { struct stu student; int fp = open("sharerd_file",O_RDONLY); struct stu *mp = mmap(NULL,sizeof(student),PROT_READ,MAP_SHARED,fp,0); if(mp == MAP_FAILED) { perror("mmap error:"); exit(1); } close(fp); printf("开始接受!!!n"); while(1) { sleep(1); printf("num = %d,name = %s,class = %dn",mp->num,mp->name,mp->class); } return 0; }

最后

以上就是等待马里奥最近收集整理的关于mmap函数mmap函数匿名映射:的全部内容,更多相关mmap函数mmap函数匿名映射内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(96)

评论列表共有 0 条评论

立即
投稿
返回
顶部