Linux system programming - shared memory mapping (interprocess communication)

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

  1. The parent process first creates the mapping area. open( O_RDWR)map( MAP_SHARED ) ;
  2. Specify MAP_SHARED permission
  3. fork() creates a child process.
  4. 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

insert image description here

Guess you like

Origin blog.csdn.net/Strive_LiJiaLe/article/details/128635064