Table of contents
mmap function
1. Function prototype
- void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t
offset);
create shared memory mapping
parameter:
- addr: Specify the first address of the mapping area. Usually pass NULL, which means let the system automatically assign
- length: the size of the shared memory mapping area
- prot: The read and write attributes of the shared memory mapping area. PROT_READ, PROT_YRITE, PROT_READ, PROT_RITE
- flags: Annotate the shared attributes of the shared memory. MAP_SHARED, IAP_PRIVATE
- fd: The file descriptor of the file used to create the shared memory-mapped area.
- offset: offset position. Must be an integer multiple of 4.
return value:
- Success: The first address of the mapping area.
- Failed: MAP_FAILED , errno
2. Create a mapping area
- int manmap(void *addr, size_t length);
Release the mapping area. - addr: the return value of mmap
- length: size
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/mman.h>
#include<fcntl.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(int argc,char *argv[])
{
char *p = NULL;
int fd;
fd = open("testmap",O_RDWR|O_CREAT|O_TRUNC,0664);
if(fd == -1)
{
sys_err("open error");
}
/*
lseek(fd,10,SEEK_END);
write(fd,"\0",1);
*/
ftruncate(fd,20);
int len = lseek(fd,0,SEEK_END);
p = mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(p == MAP_FAILED)
{
sys_err("mmap error");
}
//使用p对文件进行读写操作
strcpy(p,"hello mmap");
printf("-----%s\n",p);
int ret = munmap(p,len);
if(ret == -1)
{
sys_err("munmap error");
}
return 0;
}
3. Precautions
- 1. The size of the file used to create the mapping area is 0, but a non-zero size is actually specified to create the mapping area, and a "bus error" occurs.
- 2. The size of the file used to create the mapping area is 0, but the actual size of 0 is specified to create the mapping area, and "invalid parameter" is displayed.
- 3. The read-write attribute of the file used to create the mapping area is read-only. The attributes of the mapping area are read and write. "Invalid parameter".
- 4. To create a mapping area, read permission is required. When the access permission is specified as "shared" MAP_SHARED, the read and write permission of mmap should be <= the open permission of the file. Just writing is not enough.
- 5. The file descriptor fd can be closed after creating the mapping area in mmap. Subsequent access to files is accessed by address.
- 6. offset must be an integer multiple of 4096. (The smallest unit of MMU mapping 4 )
- 7. The memory in the mapped area of the application cannot be accessed beyond the boundary.
- 8. The address used by munmap for release must be the address returned by the mmap application.
- 9. The access right of the mapping area is "private" MAP_PRIVATE, and all modifications made to the memory are only valid in the memory and will not be reflected on the physical disk.
- 10. The access permission of the mapping area is "private" MAP_PRIVATE, only need to have read permission when opening the file, which is used to create the mapping area.
4. mmap communication between parent and child processes
- The parent process first creates the mapping area. open( O_RDWR)map( MAP_SHARED ) ;
- Specify MAP_SHARED permission
- fork() creates a child process.
- One process reads and another process writes.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/mman.h>
#include<fcntl.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>
int var = 200;
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(int argc,char *argv[])
{
int *p;
pid_t = pid;
int fd;
fd = open("testmap",O_RDWR|O_CREAT|O_TRUNC,0664);
if(fd == -1)
{
sys_err("open error");
}
ftruncate(fd,20);
p = (int *)mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(p == MAP_FAILED)
{
sys_err("mmap error");
}
close(fd); //映射区创建完毕,即可关闭文件
pid = fork(); //创建子进程
if(pid == 0){
*p = 2000; //写共享内存
var = 1000;
}else{
//父进程操作
sleep(1);
printf("parent,*p = %d,var = %d\n",*p,var);//读共享内存,var:读时共享,写时复制
wait(NULL);
int ret = munmap(p,len);//释放映射区
if(ret == -1)
{
sys_err("munmap error");
}
}
return 0;
}
4. Mmap communication between unrelated processes
- Two processes open the same file and create mapped areas.
- Specify f1ags as MAP_SHARED.
- One process writes and another process reads.
【Note】; no blood relationship between the process of communication.
- mmap: Data can be read repeatedly.
- fifo: Data can only be read once.
Write process:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/mman.h>
#include<fcntl.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>
struct student{
int id;
char name[25];
int age;
};
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(int argc,char *argv[])
{
struct student stu = {
110,"xiaom",18};
struct student *p;
int fd;
fd = open("testmap",O_RDWR|O_CREAT|O_TRUNC,0664);
if(fd == -1)
{
sys_err("open error");
}
ftruncate(fd,sizeof(stu));
p = (struct student *)mmap(NULL,sizeof(stu),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(p == MAP_FAILED)
{
sys_err("mmap error");
}
close(fd); //映射区创建完毕,即可关闭文件
while(1){
memcpy(p,&stu,sizeof(stu));
stu.id++;
sleep(1);
}
munmap(p,sizeof(stu));
return 0;
}
Read process:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/mman.h>
#include<fcntl.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>
struct student{
int id;
char name[25];
int age;
};
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(int argc,char *argv[])
{
struct student stu;
struct student *p;
int fd;
fd = open("testmap",O_RDWR|O_CREAT|O_TRUNC,0664);
if(fd == -1)
{
sys_err("open error");
}
p = (struct student *)mmap(NULL,sizeof(stu),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(p == MAP_FAILED)
{
sys_err("mmap error");
}
close(fd); //映射区创建完毕,即可关闭文件
while(1){
printf("id = %d,name = %s,age = %d",p->id,p->name,p->age);
sleep(1);
}
munmap(p,sizeof(stu));
return 0;
}
Attachment: Files are used for inter-process communication
One process reads the file and another process writes to the file