Source
Http://www.blogjava.net/sunzhong/articles/297435.html
The shared memory area is a part of the physical memory shared by multiple processes. If multiple processes map the memory area to their virtual address space, these processes can directly access the shared memory area for communication. Shared memory is the fastest way to share data between processes. When a process writes data to the shared memory area, all the processes that share the memory area can immediately see the content. This page of shared virtual memory appears in the page table of each process that shares the page. However, it does not need to have the same virtual address in the virtual memory of all processes.
Figure shared memory ing
Like all System v ipc objects, the acquisition of shared memory objects is controlled by keys. After the memory is shared, the process will no longer check how to use the memory. They must rely on other mechanisms, such as the System V signal lights, to synchronize access to the shared memory area (how the signal lights control access to critical code is another article ).
Each newly created shared memory object is expressed in a shmid_kernel data structure. All shmid_kernel data structures in the system are stored in the shm_segs vector table. Each element of this vector table is a pointer to the shmid_kernel data structure.
The shm_segs vector table is defined as follows:
Struct shmid_kernel * shm_segs [shmmni];
The shmmni value is 128, indicating that the system can have a maximum of 128 shared memory objects.
The data structure shmid_kernel is defined as follows:
Struct shmid_kernel
{
Struct shmid_ds U;/* The following are private */
Unsigned long shm_npages;/* size of segment (pages )*/
Unsigned long * shm_pages;/* array of ptrs to frames-> shmmax */
Struct vm_area_struct * attaches;/* descriptors for attaches */
};
Where:
Shm_pages indicates the Memory Page array occupied by the shared memory object. Each element in the array is of course the starting address of each memory page.
Shm_npages is the number of pages occupied by the shared memory object in pages. Of course, this quantity covers the minimum integer multiple of the applied space.
(A new shared memory segment, with size equal to the value of size rounded up to a multiple of page_size)
Shmid_ds is a data structure that describes the authentication information, the size of bytes, the last adhesion time, the separation time, the change time, and the process for creating the shared area, the last process to operate on it. The number of processes currently using it and other information.
It is defined as follows:
Struct shmid_ds {
Struct ipc_perm shm_perm;/* operation perms */
Int shm_segsz;/* size of segment (bytes )*/
_ Kernel_time_t shm_atime;/* Last attach time */
_ Kernel_time_t shm_dtime;/* Last detach time */
_ Kernel_time_t shm_ctime;/* last change time */
_ Kernel_ipc_pid_t shm_cpid;/* PID of creator */
_ Kernel_ipc_pid_t shm_lpid;/* PID of last operator */
Unsigned short shm_nattch;/* No. of current attaches */
Unsigned short shm_unused;/* compatibility */
Void * shm_unused2;/* Ditto-used by dipc */
Void * shm_unused3;/* unused */
};
Attaches describes the virtual memory area of each process mapped to the shared physical memory object. Every process that wants to share this memory must attach it to its virtual memory through a system call. This process creates a new vm_area_struct data structure that describes the shared memory for the process. During creation, you can specify the location of the virtual address space that exists in the share, or you can have Linux select a sufficient free area for it.
The new vm_area_struct structure maintains the relationship between the shared memory and the processes that use it. Therefore, in addition to associating process information, it also specifies the location of the shared memory data structure shmid_kernel. In addition, it is easy to manage these frequently changed vm_area_struct, so the chain table is used to organize the data structure. The chain table is directed by attaches. At the same time, the vm_area_struct data structure provides two pointers: vm_next_shared and vm_prev_shared, connect to the vm_area_struct data structure of the shared area in each process that uses it.
Figure System v ipc Mechanism-shared memory
Linux provides four operations for shared memory.
1. Create or obtain shared memory objects. Like the other two IPC Mechanisms, before using the shared memory area, a process must create a shared memory object whose key value is key by calling sys_ipc (the call value is shmget, or obtain the reference identifier of a shared memory object with the existing key value as the key. In the future, all accesses to shared memory objects will be carried out through the reference identifier. The sys_shmget function is used to create or obtain shared memory objects. Its definition is as follows:
Int sys_shmget (key_t key, int size, int shmflg)
Key indicates the key value of the shared memory object. Size indicates the size of the shared memory area (in bytes ), shmflg is a flag (Special requirements for this shared memory object ).
It does the following:
1) if key = ipc_private, a new shared memory object will always be created.
However (the name choice ipc_private was perhaps unfortunate, ipc_new wowould more clearly show its function)
* Calculate the number of pages to be occupied by the size and check its validity.
* Apply for a piece of memory to establish the shmid_kernel data structure. Note that the size of the memory area requested here does not include the real shared memory area. In fact, the shared memory zone is created only when the first process tries to access it.
* Based on the number of pages occupied by the shared memory area, apply for a space for creating a page table (4 bytes per page) and clear the page table 0.
* Search the vector table shm_segs to find an empty location for the newly created shared memory object.
* Fill in the shmid_kernel data structure and add it to the empty position found for the vector table shm_segs.
* Returns the reference identifier of the shared memory object.
2) Search for the shared memory object with the key value in the vector table shm_segs. The result is as follows:
* If no shared memory is found and the operation flag does not indicate that a new shared memory is to be created, an error is returned. Otherwise, a new shared memory object is created.
* If a new object whose key value is key is found, an error is returned.
* Otherwise, the system returns an error if there is an error in validity or authentication checks. Otherwise, the system returns the reference identifier of the memory object.
The creator of the shared memory object can control the access permission to the memory and whether its key is public or private. If you have sufficient permissions, it can also lock the shared memory in the physical memory.
See include/Linux/SHM. h
2. Join. After you create or obtain a reference identifier for a shared memory area, you must map the shared memory area to the virtual address space of the process before using the shared memory area. The system calls sys_ipc (the call value is shmat) to map the memory zone to the virtual address space of the process. The sys_shmat function is used to truly complete the adhesion,
It is defined as follows:
# Include <sys/types. h>
# Include <sys/SHM. h>
Void * shmat (INT shmid, const void * shmaddr, int shmflg );
Where:
Shmid is the reference identifier of the shared memory object returned by shmget;
Shmaddr is used to specify the virtual address corresponding to the virtual address space of the shared memory area in the process;
Shmflg is the ing flag;
The returned virtual address is in the process.
The function does the following:
1) Find the shared memory object based on shmid.
2) If shmaddr is 0, that is, the user does not specify the location of the shared memory area in its virtual space, the system finds a region for the virtual address space of the process (starting from 1 GB); otherwise, shmaddr is used as the mapped virtual address.
(If shmaddr is null, the system chooses a suitable (unused) address a he which to attach the segment)
3) Check the legality of the virtual address (the maximum virtual space of the process cannot exceed-3 GB, and cannot be too close to the top of the stack ).
4) authentication check.
5) apply for a piece of memory for establishing the data structure vm_area_struct and fill in the structure.
6) Check the memory area and add it to the MM structure of the process and the vm_area_struct queue of the shared memory object.
The adhesion of shared memory only creates a vm_area_struct data structure and adds it to the corresponding queue. At this time, no real shared memory page is created.
When a process accesses a page with shared virtual memory for the first time, a page fault exception occurs because all the pages with shared memory are not allocated. When Linux processes this page fault, it finds the vm_area_struct data structure where the abnormal virtual address is located. The data structure contains a group of processing programs that share the virtual memory. The nopage operation is used to process the physical page corresponding to the virtual page that does not exist. For shared memory, this operation is shm_nopage (defined in IPC/SHM. C ). This operation searches for the page in the shm_pages table that describes the shmid_kernel data structure of the shared memory.
The page table entry corresponding to the virtual address of the fault exception to check whether the shared page exists (the page table entry is 0, indicating that the shared page is used for the first time ). If it does not exist, it allocates a physical page and creates a page table entry for it. This entry not only enters the page table of the current process, but also stores it in the shm_pages page table of the shmid_kernel data structure.
When the next process tries to access this memory and get a page fault, it goes through the same path and goes to the shm_nopage function. When this function is used to view the shm_pages table of the shmid_kernel data structure, it finds that the shared page already exists. It only needs to fill in the page table items in the corresponding position of the Process page table, you do not need to recreate the physical page. Therefore, it is the first process to access the shared memory page so that this page is created, and other processes that subsequently access it only add this page to their virtual address space.
3. separation. When processes no longer need to share virtual memory, they are separated (detach ). As long as other processes are still using this memory, such separation will only affect the current process, but will not affect other processes. The vm_area_struct data structure of the current process is deleted from shmid_ds and released. The page table of the current process is also updated, and the virtual memory page corresponding to the shared memory is marked as invalid. When the last process sharing the memory is separated from it, the shared memory page is released, and the shmid_kernel data structure of the shared memory is also released.
The system calls sys_ipc (the call value is shmdt) to separate the shared memory zone from the virtual address space of the process. The function that truly completes the separation is
Sys_shmdt is defined as follows:
Int sys_shmdt (char * shmaddr)
Here, shmaddr is the starting virtual address of the shared page to be separated by the process.
This function searches all vm_area_struct data structures in the process's memory structure, finds the corresponding address shmaddr, and calls the do_munmap function to release it.
In the do_munmap function, the vm_area_struct data structure to be released is removed from the virtual memory of the process, and the page table items corresponding to the vm_area_struct in the process page table (which may occupy multiple page table items) are cleared ).
If the shared virtual memory is not locked in the physical memory, the separation is more complex. In this case, pages with shared memory may be exchanged to the system's swap disk when the system uses a large amount of memory. To avoid this situation, you can use the following control operations to lock a shared memory page in the physical memory and do not allow swap. The swap-out and swap-in of shared memory are discussed in Chapter 3rd.
4. Control. The fourth operation implemented by Linux on the shared memory is the control of the shared memory (the call value is the sys_ipc call of shmctl), which is implemented by the function sys_shmctl. Control Operations include obtaining the status of shared memory objects and setting parameters of shared memory objects (such as uid, GID, mode, and ctime ), lock and release shared memory objects in the memory (add or remove the shm_locked mark on the object mode), and release shared memory object Resources.
Shared Memory provides a fast and flexible mechanism that allows processes to directly share a large amount of data without using copies or system calls. The main limitation of shared memory is that it cannot provide synchronization. If two processes attempt to modify the same shared memory area, because the kernel Cannot serialize these actions, the written data may be mixed randomly. Therefore, processes that use shared memory must design their own synchronization protocols, such as using traffic signals.
The following are basic operations for inter-process communication using the shared memory mechanism:
Header files to be included:
# Include <sys/types. h>
# Include <sys/IPC. h>
# Include <sys/SHM. h>
1. Create shared memory:
Int shmget (key_t key, int size, int shmflg );
Parameter description:
Key: a keyword used to indicate a new or existing shared memory.
Size: the size of the shared memory.
Shmflg: A special flag that can be specified. Ipc_create, ipc_excl, and nine-bit permission.
Eg:
Int shmid;
Shmid = shmget (ipc_private, 4096, ipc_create | ipc_excl | 0660 );
If (shmid =-1)
Perror ("shmget ()");
2. Connect to the shared memory
Char * shmat (INT shmid, char * shmaddr, int shmflg );
Parameter description
Shmid: Shared Memory keyword
Shmaddr: Specifies the location where the shared memory appears in the process memory address. Generally, let the kernel decide a proper address location and set it to 0 when used.
Shmflg: Specifies a special flag.
Eg:
Int shmid;
Char * shmp;
Shmp = shmat (shmid, 0, 0 );
If (shmp = (char *) (-1 ))
Perror ("shmat () \ n ");
3. Use shared memory
When using shared memory, we should note that we generally use it with semaphores to prevent memory access conflicts.
4. Separated shared memory: when the program no longer needs to share the memory, we need to separate the shared memory to release it. The original function of splitting the shared memory is as follows:
Int shmdt (char * shmaddr );
5. Release shared memory
Int shmctl (INT shmid, int cmd, struct shmid_ds * BUF );