Linux shm shared memory

The simplest and most direct way to achieve inter-process communication is to share memory - opening up a shared area in memory for multiple processes participating in communication. Since the process can directly read and write shared memory, this communication method is particularly efficient. However, its weakness is that there is no mutual exclusion mechanism, and means such as semaphores are needed to cooperate with Linux's shared memory
.

  1. Shared memory principle
  2. Linux shared memory structure
  3. Shared memory usage

Shared memory principle

Shared memory, as the name suggests, is the same memory space that can be accessed by two or more processes. Modifications to the contents of this space by one process can be seen by other processes participating in the communication. In order to achieve this goal, two things need to be done thing:

  1. Create an area in memory as a shared area
  2. The usual way to map this area to the space of each process participating in communication
    is to open a file in the memory. If the system calls mmap(), the memory space occupied by this file is mapped to each process participating in communication. process address space, then these processes can see this shared area, thereby realizing inter-process communication.

Brief description of the principle of mmap()

void * mmap(void *start, size_t len, int prot, int flags, int fd, off_t offset);

start is used to specify the starting position mapped to the virtual address space (usually NULL, which is determined by the system)
len specifies the length of the mapped part of the file;

fd is used to specify the mapped file
offset to specify the starting position offset of the mapping (usually 0)
mmap is a method of memory mapping files: that is, mapping a file or other object to the address space of the process to implement the file disk address A one-to-one mapping relationship with a virtual address in the process virtual address space. After realizing such a mapping relationship, the process can use pointers to read and write this memory, and the system will automatically write back the dirty pages to the corresponding file disk, that is, the file operation is completed without calling read and write. Wait for system call functions. On the contrary, the modification of this area by the kernel space also directly reflects the user space, thus enabling file sharing between different processes.

mmap mapping process:
Insert image description here
mmap is a simple operation. Add a page table entry (the address of physical memory) to the process page table.
When mmap is called, the kernel will search for a space that meets the requirements in the mapping area of ​​the process's address space. To map the file, and then generate a page table entry for the virtual address. The valid bit of the page table at this time (marking whether it is already in physical memory) is 0, and the content of the page table entry is the disk address of the file.
bref means adding a segment to the virtual memory segment corresponding to the process, that is, creating a new vm_area_struct and connecting it to the physical disk address of the file.
A virtual interval is created and address mapping is completed, but no file data is copied to main memory. Real file reading occurs when a process initiates a read or write operation.
The read and write operations of the process access the mapped address of the virtual address space. By querying the page table, a page exception is caused, and the kernel requests the page.

The shared memory access method of IPC is very similar to the mmap() method, but because the purpose of creating a file is only for communication, this kind of file has no meaning of permanent storage, so IPC does not use a regular file system, but initializes the system . At that time, a temporary file system shm was established in the disk swap area specifically to implement shared memory . When the system is powered off, all files in it will be automatically destroyed.

Linux shared memory structure

  1. A shared memory area in Linux consists of multiple shared segments . The kernel data structure shmid_kernel is used to describe the shared memory segments:
struct shmid_kernel /* private to the kernel */
{
    
    	
	struct kern_ipc_perm	shm_perm;			//描述进程间通信许可的结构permission
	struct file *			shm_file;			//指向共享内存文件的指针
	unsigned long			shm_nattch;			//挂接到本段共享内存的进程数
	unsigned long			shm_segsz;			//段大小segmataion size
	time_t					shm_atim;			//最后挂接时间attach time
	time_t					shm_dtim;			//最后解除挂接时间delete time
	time_t					shm_ctim;			//最后变化时间change time
	pid_t					shm_cprid;			//创建进程的PID
	pid_t					shm_lprid;			//最后使用进程的PID
	struct user_struct		*mlock_user;
};

The most important field in shmid_kernel is the pointer shm_file, which points to the temporary file file object. When a process needs to use this file for communication, the kernel is responsible for mapping it into user address space.

  1. In order to facilitate management, the kernel stores all co-descriptive structures shmid_kernel in the shared memory area in the structure ipc_id_ary (shared memory segment data/collection):
struct ipc_id_ary
{
    
    
        int			size;
        struct		kern_ipc_perm *p[0];	//存放段描述结构的数组
};
  1. Likewise, to describe an overview of a shared memory area, the kernel uses the data structure ipc_ids . The structure is defined as follows:
struct ipc_ids {
    
    
	int				in_use;
	unsigned short	seq;
	unsigned short	seq_max;
	struct			rw_semaphore rw_mutex;
	struct			idr ipcs_idr;
    struct			ipc_id_ary *entries;        //指向struct ipc_id_ary的指针
};

The structure of a shared area composed of multiple shared segments is as follows:
Insert image description here

Shared memory usage

#include <sys/shm.h>
  1. Open or create shared memory
int shmget(key_t key, size_t size, int flag);
  1. Shared memory and process connection
void * shmat(int shmid, char __user * shmaddr, int shmflg);
  1. Shared memory is disconnected from the process
int shmdt(coid * addr);
  1. Shared memory control
int shmctl(int shmid, int cmd, struct shmid_ds * buf);

Shared memory will not be automatically eliminated when the program ends. Either call shmctl() to delete it, or manually use the command ipcrm -m shmid to delete it. Otherwise, it will remain in the system until the system is powered off.

Guess you like

Origin blog.csdn.net/weixin_44280688/article/details/103077251