当前位置:网站首页>mmap、munmap
mmap、munmap
2022-04-23 20:46:00 【baboon_ chen】
List of articles
One 、 Function declaration
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
/* Parameters : addr: Create the first address of the mapping area , from linux Kernel specification . When using , Direct delivery NULL length: The size of the mapping area you want to create prot: Map area permissions PROT_READ、PROT_WRITE、PROT_READ|PROT_WRITE flags: Flag bit parameters MAP_SHARED: The operation of the mapping area will be reflected on the physical disk . MAP_PRIVATE: Changes made in the mapping area will not be reflected in the physical device . fd: The file descriptor used to create the mapping area offset: The offset of the mapping file (4K Integer multiple , Can't pass 4095、4098 etc. ) */
/* Return value : success : Return the first address of the created mapping area Failure :MAP_FAILED macro */
int munmap(void *addr, size_t length);
/* Parameters : addr: mmap Return address length: mmap Create the size of the mapping area */
/* Return value : success : 0 Failure : -1, and errno is set */
Two 、 Access disk files with shared memory
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h> //mmap munmap
#include <fcntl.h>
#include <stdlib.h>
int main()
{
// Open file
int fd = open("./my_file.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fd == -1)
{
perror("open file failed.");
exit(EXIT_FAILURE);
}
// Set file size
unsigned fileSize = 64;
int ret = ftruncate(fd, fileSize);
if (ret == -1)
{
perror("open file failed.");
exit(EXIT_FAILURE);
}
// Set up memory mapping
char *p = (char *)mmap(NULL, fileSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (p == MAP_FAILED)
{
perror("mmap failed.");
exit(EXIT_FAILURE);
}
// Write information to the file
strcpy(p, "hello, world!\n");
munmap(p, fileSize);
close(fd);
return 0;
}
3、 ... and 、mmap Precautions for use
1、open When you file , Sure O_CREAT Create a new file to create the mapping area ?
Sure , But you need to set the file size , Otherwise, the newly created file size is 0,mmap The size of the created mapping area is 0.
2、 If the address returned by the parameter isaddr++
operation ,mumap Whether it will succeed ?
You can't , When releasing the mapping area , You need to pass in the return address of creating the mapping area , Mapping area size , Must be consistent .
3、 If open Time use O_RDONLY, and mmap It's timePROT_READ|PROT_WRITE
What will happen ?
WhenMAP_SHARED
when , It is required that the permission to create the mapping area should be less than or equal to the permission to open the file ( For the protection of the mapping area ).
andMAP_PRIVATE
There is no demand for , because mmap The permission in is to limit memory .
During the creation of the mapping area, there is an implicit read operation of the file .
4、 If the file offset is set to 1000 What will happen ?
the last one offset The size of must be4K
Integer multiple ( One memory page size ),mmu
In the process of mapping , The unit is4K
.
5、 If not detected mmap The return value of , What will happen ?
mmap The probability of creating a mapping area is very high , Be sure to check the return value , Make sure that the mapping area is successfully established before the subsequent operations .
6、mmap Under what circumstances will the call fail ?
The size of the mapping area cannot be larger than the file size .
7、 Yes addr What happens when a process goes out of bounds ?
Meeting core.
8、 The file descriptor closes first , Yes mmap Does mapping affect ?
No effect . The so-called file descriptor is only used to manipulate the handle of the file ,mmap The way to manipulate files is to manipulate files through addresses , Once the mapping area is created successfully , File descriptors no longer work , It can be turned off .
Four 、mmap Used for communication between parent and child processes
Father and son and other blood related processes can also be passed through mmap To complete the mapping of the data area . However, when creating a mapping area, specify the corresponding flag bit parameters flags:
MAP_PRIVATE
:( Private mapping ) The parent and child processes own the mapping area ;
MAP_SHARED
:( Share mapping ) The parent and child processes share the mapping area ;
#include <sys/mman.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int v = 100;
// Create temporary file
int fd = open("./tmp", O_RDWR | O_CREAT |O_TRUNC, 0644);
if (fd == -1)
{
perror("open file failed.");
exit(EXIT_FAILURE);
}
unlink("./tmp"); // Delete temporary file directory entry , Make it ready for release . When the process is no longer occupied, delete the file .
ftruncate(fd, 4);
int *p = (int *)mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
// The parent-child processes do not share the mapping area
//int *p = (int *)mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (p == MAP_FAILED)
{
perror("mmap failed.");
exit(EXIT_FAILURE);
}
close(fd);
pid_t pid = fork();
if (pid == 0)
{
v = 1000;
*p = 1000;
printf("child v=%d, *p=%d\n", v, *p);
}
else if (pid > 0)
{
sleep(1);
printf("parent v=%d, *p=%d\n", v, *p);
wait(NULL);
int ret = munmap(p, 4);
if (ret == -1)
{
perror("munmap failed.");
exit(EXIT_FAILURE);
}
}
return 0;
}
Conclusion :
The parent-child process shares :
1、 Open file
2、mmap Set up the mapping area ( But you have to use MAP_SHARED)
5、 ... and 、 Anonymous mapping area
By using it, we find that , It is very convenient to use the mapping area to read and write files , Communication between parent and child processes is also easier , But the flaw is , Each time you create a mapping area, you must rely on a file to achieve . Usually, in order to establish the mapping area, we need to open One temp file , Create it and then unlink,close fall , More trouble . You can use anonymous mapping directly instead of . Actually linux The system provides us with the method of creating anonymous mapping area , No need to rely on a file to create a mapping area . Also need to use the flag bit parameter falgs Come on Appoint .
Use MAP_ANONYMOUS
( or MAP_ANON
), Such as :
int *p = (int *)mmap(NULL, 4, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
// 4 It's a random example , Represent size
// fd == -1, No need to transfer file descriptor
// flags == MAP_SHARED|MAP_ANONYMOUS
It should be noted that ,MAP_ANONYMOUS
and MAP_ANON
These two macros are linux Operating system specific macro . In the class Unix If there is no macro definition in the system , You can use the following two steps to complete the establishment of anonymous mapping area .
fd = open("/dev/zero", O_RDWR);
P = mmap(NULL, size, PROT_READ|PROT_WRITE, MMAP_SHARED, fd, 0);
Example :
#include <sys/mman.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int v = 100;
int *p = (int *)mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED |MAP_ANONYMOUS, -1, 0);
if (p == MAP_FAILED)
{
perror("mmap failed.");
exit(EXIT_FAILURE);
}
pid_t pid = fork();
if (pid == 0)
{
v = 1000;
*p = 1000;
printf("child v=%d, *p=%d\n", v, *p);
}
else if (pid > 0)
{
sleep(1);
printf("parent v=%d, *p=%d\n", v, *p);
wait(NULL);
int ret = munmap(p, 4);
if (ret == -1)
{
perror("munmap failed.");
exit(EXIT_FAILURE);
}
}
return 0;
}
6、 ... and 、mmap Used for non consanguineous inter process communication
mmap_write.c
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/mman.h>
struct STU {
int id;
char name[20];
char sex;
};
void sys_err(const char *str)
{
perror(str);
exit(EXIT_FAILURE);
}
int main(int argc, char **argv)
{
int fd;
struct STU stu = {
10, "xiaoming", 'm'};
struct STU *p;
if (argc < 2) sys_err("./a.out file_shared\n");
fd = open(argv[1], O_RDWR|O_CREAT, 0644);
if (fd == -1) sys_err("open error");
// After creating the file successfully , Be sure to remember to set the file size , Otherwise it will be reported Bus error
ftruncate(fd, sizeof(stu));
p = (struct STU *)mmap(NULL, sizeof(stu), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) sys_err("mmap error");
close(fd);
// Every second , to update mmap The content in .
while (1)
{
memcpy(p, &stu, sizeof(stu));
stu.id++;
sleep(1);
}
munmap(p, sizeof(stu));
return 0;
}
mmap_read.c
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
struct STU {
int id;
char name[20];
char sex;
};
void sys_err(const char *str)
{
perror(str);
exit(EXIT_FAILURE);
}
int main(int argc, char **argv)
{
int fd;
struct STU stu;
struct STU *p;
if (argc < 2) sys_err("./a.out file_shared\n");
fd = open(argv[1], O_RDONLY);
if (fd == -1) sys_err("open error");
p = (struct STU *)mmap(NULL, sizeof(stu), PROT_READ, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) sys_err("mmap error");
close(fd);
// Every two seconds , Read mmap The content in .
while (1)
{
printf("stu.id = %d\t stu.name=%s\t stu.sex = %c\n", p->id, p->name, p->sex);
sleep(2);
}
munmap(p, sizeof(stu));
return 0;
}
版权声明
本文为[baboon_ chen]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204210546350929.html
边栏推荐
- go array
- Resolve the error - error identifier 'attr_ id‘ is not in camel case camelcase
- 3-5通过XSS获取cookie以及XSS后台管理系统的使用
- Recommended usage scenarios and production tools for common 60 types of charts
- C migration project record: modify namespace and folder name
- SQL: query duplicate data and delete duplicate data
- GSI-ECM工程建设管理数字化平台
- 深入探究ASP.NET Core读取Request.Body的正确方式
- The more you use the computer, the slower it will be? Recovery method of file accidental deletion
- How to learn software testing? Self study or training? After reading this article, you will understand
猜你喜欢
Linux中,MySQL的常用命令
Zhongchuang storage | how to choose a useful distributed storage cloud disk
DOS command of Intranet penetration
Another data analysis artifact: Polaris is really powerful
On the three paradigms of database design
go defer
LeetCode 116. 填充每个节点的下一个右侧节点指针
C migration project record: modify namespace and folder name
Matlab matrix index problem
Vulnhub DC: 1 penetration notes
随机推荐
Parsing methods of JSON data in C - jar and jobobject: error reading jar from jsonreader Current JsonReader item
MySQL基础之写表(创建表)
MySQL advanced common functions
100天拿下11K,转岗测试的超全学习指南
C migration project record: modify namespace and folder name
Introduction to intrusion detection data set
Flex layout
The iswow64process function determines the number of program bits
Is qiniu school useful and is the recommended securities account safe
Syntaxerror: unexpected token r in JSON at position 0
Async function ------ ES6
How to learn software testing? Self study or training? After reading this article, you will understand
Vulnhub DC: 1 penetration notes
Learn to C language fourth day
Send email to laravel
Leetcode 542, 01 matrix
MySQL数据库常识之储存引擎
MySQL基础合集
[matlab 2016 use mex command to find editor visual studio 2019]
Zhongchuang storage | how to choose a useful distributed storage cloud disk