当前位置:网站首页>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
边栏推荐
- Is qiniu school useful and is the recommended securities account safe
- Easy to use nprogress progress bar
- 浅谈数据库设计之三大范式
- LeetCode 1351、统计有序矩阵中的负数
- Unity Odin ProgressBar add value column
- Latex formula
- Bash script learning -- for loop traversal
- Scripy tutorial - (2) write a simple crawler
- Go language development Daily Fresh Project Day 3 Case - Press Release System II
- Learn to C language fourth day
猜你喜欢
Common commands of MySQL in Linux
Unity Odin ProgressBar add value column
Case of the third day of go language development fresh every day project - news release system II
[PTA] l1-002 printing hourglass
PHP的Laravel与Composer部署项目时常见问题
Leetcode 994, rotten orange
LeetCode 542、01 矩阵
High paid programmer & interview question series 91 limit 20000 loading is very slow. How to solve it? How to locate slow SQL?
2021-09-02 unity project uses rider to build hot change project failure record of ilruntime
[stack and queue topics] - sliding window
随机推荐
Solve the Chinese garbled code of URL in JS - decoding
LeetCode 116. Populate the next right node pointer for each node
3-5 obtaining cookies through XSS and the use of XSS background management system
Commande dos pour la pénétration de l'Intranet
MySQL stored procedures and functions
MySQL 存储过程和函数
The more you use the computer, the slower it will be? Recovery method of file accidental deletion
打新债中签以后怎么办,网上开户安全吗
BMP JPEG picture to vector image contourtrace
Install MySQL 5.0 under Linux 64bit 6 - the root password cannot be modified
MySQL advanced common functions
Thirty What are VM and VC?
一些接地气的话儿
2021-06-29 C escape character cancellation and use
Fastdfs思维导图
High paid programmer & interview question series 91 limit 20000 loading is very slow. How to solve it? How to locate slow SQL?
Addition, deletion, modification and query of advanced MySQL data (DML)
又一款数据分析神器:Polars 真的很强大
How to use PM2 management application? Come in and see
Awk print special characters