System v ipc (3)-shared memory, ipc
I. Overview
1. Shared memory allows multiple processes to share the same block of physical memory.
2. Unlike pipelines and message queues, there is user memory space in the share, and no kernel intervention is required. Reduces the data replication overhead of the kernel and user buffer. Therefore, this IPC is faster.
3. When multiple processes share memory, other synchronization mechanisms are required to control the critical section, such as the semaphore in the previous article.
Ii. Function Interfaces
1. Create or enable shared memory
1 #include <sys/shm.h>2 3 int shmget(key_t key, size_t size, int shmflg);
Key and shmflg are the same as message queues and semaphores.
Size: The size of memory to be allocated.
2. Use shared memory
1 #include <sys/shm.h>2 3 void *shmat(int shmid, const void *shmaddr, int shmflg);
Shmid: value returned by shmget ()
Shmaddr: point the newly created memory to this pointer. If it is NULL, the kernel is automatically selected.
Shmflg: If shmaddr is not NULL, shmflg controls shmaddr if it points to memory. For example, read-only memory and calculate memory address multiples, you can view the man manual.
3. Separate shared memory
1 #include <sys/shm.h>2 3 4 int shmdt(const void *shmaddr);
Shmaddr is the pointer of the process to the shared memory. Detach the shared memory from the process, that is, the shared memory is not associated with the process. After separation, the coexistence memory still exists.
4. Control shared memory
1 #include <sys/shm.h>2 3 int shmctl(int shmid, int cmd, struct shmid_ds *buf);
Like message queue, cmd deletes the shared memory.
Iii. Simple examples
We write two small programs. The first is to create and copy data to the shared memory, and the second is to read and delete the shared memory.
1. Create and copy
1/** 2 * @ file shm1.c 3 */4 5 # include <stdio. h> 6 # include <stdlib. h> 7 # include <string. h> 8 # include <sys/shm. h> 9 10 # define pai_mem_buf_size 102411 12 void err_exit (const char * err_msg) 13 {14 printf ("error: % s \ n", err_msg); 15 exit (1 ); 16} 17 18 int main (void) 19 {20 int shm_id; 21 void * pai_mem; 22 char * text = "123456"; 23 24 shm_id = shmget (IPC_PRIVATE, pai_mem_buf_size, 0666 | IPC_CREAT); 25 if (shm_id =-1) 26 err_exit ("shmget ()"); 27 28 printf ("shm_id: % d \ n", shm_id ); 29 30/* point the created shared memory to a pointer to the Program */31 pai_mem = shmat (shm_id, NULL, 0); 32 if (pai_mem = (void *) -1) 33 err_exit ("shmat ()"); 34 35/* Copy data to the shared memory */36 memcpy (char *) 1__mem, text, strlen (text); 37 38/* Split shared memory */39 if (shmdt (mongo_mem) =-1) 40 err_exit ("shmdt ()"); 41 42 return 0; 43}
2. Read and delete
1/** 2 * @ file shm2.c 3 */4 5 # include <stdio. h> 6 # include <stdlib. h> 7 # include <string. h> 8 # include <sys/shm. h> 9 10 # define pai_mem_buf_size 102411 12 void err_exit (const char * err_msg) 13 {14 printf ("error: % s \ n", err_msg); 15 exit (1 ); 16} 17 18 int main (int argc, const char * argv []) 19 {20 if (argc <2) 21 {22 printf ("usage: % s shm_id \ n ", argv [0]); 23 exit (1); 24} 25 26 void * 1__mem; 27 int shm_id = atoi (argv [1]); 28 29/* point the created shared memory to a pointer to the Program */30 pai_mem = shmat (shm_id, NULL, 0); 31 if (pai_mem = (void *) -1) 32 err_exit ("shmat ()"); 33 34/* read data */35 printf ("read data: % s \ n", (char *) share_mem); 36 37/* separate shared memory */38 if (shmdt (mongo_mem) =-1) 39 err_exit ("shmdt ()"); 40 41/* Delete shared memory */42 if (shmctl (shm_id, IPC_RMID, 0) =-1) 43 err_exit ("shmctl ()"); 44 45 return 0; 46}
Iv. Experiment
1. shm1.c uses IPC_PRIVATE to enable the kernel to automatically create a key and allocate 1024 bytes of memory. Row 3 copies "36th" to the shared memory.
2. shm2.c specifies the shared memory to be used from the command line, reads data from 35th rows, and deletes data from 42nd rows.
3. After running shm1, you can get the shmid of the shared memory. You can view it using ipcs-m | grep 'xxx:
We can see the allocated 1024 bytes of memory.
4. Run shm2 to receive data with shmid = 50954258 and delete the shared memory, and then use ipcs-m | grep 'xxx' to view:
You can see that the data "123456" has been read and deleted when you use ipcs to view the data.