Shared memory is the fastest and most efficient form of interprocess communication, and when shared memory is mapped to the address space of a process that shares it, the data transfer between processes is no longer involved in the kernel, and the process can read the kernel directly without having to copy the data through the kernel system calls. In general usage, there is a need for synchronization between processes that write or read data from shared memory, such as through semaphores and mutexes.
Shared memory has System V shared memory and POSIX shared memory, this article describes System V shared memory.
System v Shared Memory header file and related function prototypes:
#include <sys/shm.h>
int Shmget (key_t key, size_t size, int oflag);
Function: Create a new shared memory area, or access a shared memory area that already exists.
Return value: If the identifier for the shared memory area is returned successfully, return 1 if there is an error
Parameters: Key is a value, can be generated with Ftok, can also be used ipc_private; Size is the size of the memory area specified in bytes, when a new shared memory area is created, a size value of not 0 is specified, and the size byte is initialized to 0, and when an existing shared memory area is used, the size value needs to be 0; Oflag is read-write and can also be used with ipc_creat or ipc_creat| IPC_EXCL bitwise OR.
void *shmat (int shmid, const void *shmaddr, int flag);
Function: Maps the shared memory area created by Shmget to the address space of the calling process.
Return value: Returns 1 if an error occurs if the start address of the mapping area is returned successfully.
Parameters: Shmid is the identifier returned by Shmget, SHMADDR is the specified address pointer, if it is a null pointer, the system will automatically assign the address, which is the best use of portability, is the recommended usage, if SHMADDR is a non-null pointer, The mapped area address returned depends on whether the third parameter flag specifies SHM_RND, if no shm_rnd is specified, the map address is attached to the address specified by the SHMADDR parameter, and if SHM_RND is specified, The map address is attached to the address specified by the SHMADDR parameter down a Shmlba constant; flag defaults to 0 for read-write, and if shm_rdonly represents read-only access.
int SHMDT (const void *SHMADDR);
Function: Close this shared memory area mapping, when the process terminates, the shared memory map is automatically closed, but not deleted, can be removed by the SHMCTL function of the Ipc_rmid command.
Return value: Successfully returned 0, error returned-1
int shmctl (int shmid, int cmd, struct shmid_ds *buf);
Function: Operation Shared memory Area
Return value: Successfully returned 0, error returned-1.
Parameters: The cmd parameter has three commands, Ipc_rmid removes the shmid labeled Shared memory area from the system, Ipc_set sets the three members of the SHMID_DS structure to the specified shared memory area Shm_perm.uid,shm_perm.gid and Shm_ Perm.mode, the values of these three members are derived from the corresponding members in the structure that the BUF parameter points to, Ipc_stat is the SHMID_DS structure taken from the shared memory area and saved in the parameter BUF structure.
The general programming steps are as follows:
1. Create Shared Memory:
Create shared memory through function shmget ()
2. Mapping Shared Memory:
Mapping shared memory created to a process through the function shmget ()
3. Use shared Memory:
4. Undo Shared Memory Mappings
function Shmdt ()
5. Delete the shared memory map:
function Shmctl ()
code example SHM_TEST.C: The parent process reads data from the terminal into the shared memory, and the child process reads the data from the shared memory to display to the terminal
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/shm.h>
- #define BUFFER_SIZE 1024
- int main () {
- pid_t pid;
- int shmid;
- Char *shm_addr;
- Char flag[]= "Parent";
- Char Buff[buffer_size];
- Create private shared memory for the current process
- if ((Shmid=shmget (ipc_private,buffer_size,0666)) <0) {
- Perror ("Shmget");
- Exit (1);
- } else
- printf ("Create Shared Memory:%d.\n", Shmid);
- IPCS command write to standard output some information about the communication facilities between the active interprocess
- -M indicates shared memory
- printf ("Created Shared Memory status:\n");
- System ("ipcs-m");
- if ((Pid=fork ()) <0) {
- Perror ("fork");
- Exit (1);
- }else if (pid==0) {
- Automatic allocation of shared memory mapped addresses, readable writable, mapped addresses returned to SHM_ADDR
- if ((Shm_addr=shmat (shmid,0,0)) = = (void*)-1) {
- Perror ("Child:shmat");
- Exit (1);
- }else
- printf ("Child:attach shared-memory:%p.\n", shm_addr);
- printf ("Child Attach Shared Memory status:\n");
- System ("ipcs-m");
- Compare the characters of shm_addr,flag with the length of strlen (flag)
- Returns 0 when its contents are the same
- Otherwise return (Str1[n]-str2[n])
- while (STRNCMP (Shm_addr,flag,strlen (flag))) {
- printf ("Child:waiting for data...\n");
- Sleep (10);
- }
- strcpy (Buff,shm_addr+strlen (flag));
- printf ("Child:shared-memory:%s\n", buff);
- Delete the shared memory mapped address of the child process
- if (SHMDT (SHM_ADDR) <0) {
- Perror ("Child:shmdt");
- Exit (1);
- }else
- printf ("Child:deattach shared-memory.\n");
- printf ("Child Deattach Shared Memory status:\n");
- System ("ipcs-m");
- }else{
- Sleep (1);
- Automatic allocation of shared memory mapped addresses, readable writable, mapped addresses returned to SHM_ADDR
- if ((Shm_addr=shmat (shmid,0,0)) = = (void*)-1) {
- Perror ("Parent:shmat");
- Exit (1);
- }else
- printf ("Parent:attach shared-memory:%p.\n", shm_addr);
- printf ("Parent Attach shared Memory status:\n");
- System ("ipcs-m");
- Shm_addr to Flag+stdin
- Sleep (1);
- printf ("\ninput string:\n");
- Fgets (Buff,buffer_size-strlen (flag), stdin);
- strncpy (Shm_addr,flag,strlen (flag));
- strncpy (Shm_addr+strlen (flag), Buff,strlen (buff));
- Delete the shared memory mapped address of the parent process
- if (SHMDT (SHM_ADDR) <0) {
- Perror ("Parent:shmdt");
- Exit (1);
- }else
- printf ("Parent:deattach shared-memory.\n");
- printf ("Parent Deattach shared Memory status:\n");
- System ("ipcs-m");
- Ensures that the child process can read the contents of the shared memory before the parent process deletes the shared memory
- Waitpid (pid,null,0);
- Delete Shared memory
- if (Shmctl (shmid,ipc_rmid,null) ==-1) {
- Perror ("Shmct:ipc_rmid");
- Exit (1);
- }else
- printf ("Delete shared-memory.\n");
- printf ("Child Delete Shared Memory status:\n");
- System ("ipcs-m");
- printf ("finished!\n");
- }
- Exit (0);
- }
Copy Code
Operation Result:
$./a.out
Create shared memory:65536.
Created Shared Memory Status:
------Shared Memory Segments--------
Key shmid owner perms bytes nattch Status
0x00000000 65536 Dongxw 666 2048 0
Child:attach shared-memory:0x7fc3519fe000.
Child Attach Shared memory status:
------Shared Memory Segments--------
Key shmid owner perms bytes nattch Status
0x00000000 65536 DONGXW 666 2048 1
Child:waiting for data ...
Parent:attach shared-memory:0x7fc3519fe000.
Parent Attach Shared Memory Status:
------Shared Memory Segments--------
Key shmid owner perms bytes nattch Status
0x00000000 65536 DONGXW 666 2048 2
Input string:
Child:waiting for data ...
Child:waiting for data ...
This is data
Parent:deattach shared-memory.
Parent Deattach Shared Memory Status:
------Shared Memory Segments--------
Key shmid owner perms bytes nattch Status
0x00000000 65536 DONGXW 666 2048 1
Child:shared-memory:this is Data
Child:deattach shared-memory.
Child Deattach Shared memory status:
------Shared Memory Segments--------
Key shmid owner perms bytes nattch Status
0x00000000 65536 Dongxw 666 2048 0
Delete shared-memory.
Child Delete Shared memory status:
------Shared Memory Segments--------
Key shmid owner perms bytes nattch Status
finished!
You can see the red callout data entered from the terminal "This is data", the parent process reads the write to the shared memory area, the child process reads from the shared memory and then displays to the terminal red callout "child:shared-memory:this is Data"
System v Shared memory and code examples for inter-process communication between Linux