当前位置:网站首页>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_WRITEWhat will happen ?
WhenMAP_SHAREDwhen , 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_PRIVATEThere 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 be4KInteger multiple ( One memory page size ),mmuIn 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
边栏推荐
- LeetCode 1346、检查整数及其两倍数是否存在
- Parsing methods of JSON data in C - jar and jobobject: error reading jar from jsonreader Current JsonReader item
- Async function ------ ES6
- Thirty What are VM and VC?
- LeetCode 20、有效的括号
- [PTA] l1-006 continuity factor
- Easy to use nprogress progress bar
- 笔记本电脑卡顿怎么办?教你一键重装系统让电脑“复活”
- Unity solves Z-fighting
- 內網滲透之DOS命令
猜你喜欢

On the three paradigms of database design

笔记本电脑卡顿怎么办?教你一键重装系统让电脑“复活”

Elastic box model

2022dasctf APR x fat epidemic prevention challenge crypto easy_ real

Scripy tutorial - (2) write a simple crawler

Go zero framework database avoidance Guide

Unity solves Z-fighting

Shanghai responded that "flour official website is an illegal website": neglect of operation and maintenance has been "hacked", and the police have filed a case

居家第二十三天的午饭

又一款数据分析神器:Polars 真的很强大
随机推荐
100天拿下11K,转岗测试的超全学习指南
Leetcode 1346. Check whether integers and their multiples exist
Cmake project under vs2019: calculating binocular parallax using elas method
启牛学堂有用吗,推荐的证券账户是否安全
Resolve the eslint warning -- ignore the warning that there is no space between the method name and ()
Syntax Error: TypeError: this. getOptions is not a function
MySQL基础合集
Async function ------ ES6
Come in and teach you how to solve the problem of port occupation
The construction and use of Fortress machine and springboard machine jumpserver are detailed in pictures and texts
MySQL 存储过程和函数
Addition, deletion, modification and query of advanced MySQL data (DML)
Commande dos pour la pénétration de l'Intranet
深入探究ASP.NET Core读取Request.Body的正确方式
Shanghai responded that "flour official website is an illegal website": neglect of operation and maintenance has been "hacked", and the police have filed a case
Shanghai a répondu que « le site officiel de la farine est illégal »: l'exploitation et l'entretien négligents ont été « noirs » et la police a déposé une plainte
Selenium displays webdriverwait
Leetcode 542, 01 matrix
电脑越用越慢怎么办?文件误删除恢复方法
Use of node template engine