Linux interprocess communication-Using shared memory The following will explain another way of communicating between processes, using shared memory. First, what is shared memory as the name implies, shared memory is to allow two unrelated processes to access the same logical memory. Shared memory is a very efficient way to share and pass data between two running processes. Memory that is shared between different processes is usually scheduled as the same piece of physical memory. Processes can connect the same piece of shared memory to their own address space, and all processes can access the addresses in the shared memory as if they were allocated by the C-language function malloc. If a process writes data to shared memory, the changes will immediately affect any other process that can access the same piece of shared memory. Special reminder: Shared memory does not provide a synchronization mechanism, that is, there is no automatic mechanism to prevent the second process from reading the shared memory until the first process finishes writing it. So we usually need to use other mechanisms to synchronize access to shared memory, such as the amount of semaphores mentioned earlier. For more information about semaphores, you can check out my other article: Linux interprocess communication-using semaphore two, shared memory makes the same set of function interfaces for using shared memory as the semaphore, and interfaces with shared coexistence are very similar to semaphores, And it's simpler than using a semaphore interface. They are declared in the header file sys/shm.h. 1. Shmget function This function is used to create shared memory, and its prototype is:
int int SHMFLG);
The first parameter, like the Semget function of the semaphore, requires that the program provide a parameter key (not a 0 integer), which effectively names the shared memory segment, and returns a shared memory identifier (non-negative integer) associated with the key when the Shmget function succeeds, for subsequent shared memory functions. The call failed to return-1. Unrelated processes can access the same shared memory through the return value of the function, which represents a resource that the program may want to use, and the program accesses all shared memory indirectly, first by calling the Shmget function and providing a key. A corresponding shared memory identifier (the return value of the Shmget function) is generated by the system, and only the Shmget function uses the semaphore key directly, and all other semaphore functions use the semaphore identifier returned by the Semget function. The second parameter, in bytes, specifies the amount of memory that needs to be shared. The third parameter, SHMFLG is the permission flag, which functions as the mode parameter of the Open function, and if it is to be created if the shared memory that the key identifies does not exist, it can be done or manipulated with ipc_creat. The permission flags for shared memory are the same as the read and write permissions for a file, for example, 0644, which means that shared memory that is allowed to be created by a process is read and written to shared memory by processes owned by the memory creator, while processes created by other users can read only shared memory. 2. When the Shmat function first creates the shared memory, it cannot be accessed by any process, and the Shmat function is used to initiate access to the shared memory and connect the shared memory to the address space of the current process. Its prototype is as follows:
void *shmat (intconstvoidint shmflg);
The first parameter, shm_id, is the shared memory identity returned by the Shmget function. The second parameter, SHM_ADDR, specifies that the shared memory is connected to the address location in the current process, which is usually empty, indicating that the system chooses the address of the shared memory. The third parameter, SHM_FLG, is a set of flag bits, typically 0. When the call succeeds, returns a pointer to the first byte of shared memory if the call fails to return-1. 3. Shmdt function This function is used to detach shared memory from the current process. Note that separating shared memory is not removing it, just making that shared memory no longer available to the current process. Its prototype is as follows:
int shmdt (constvoid *shmaddr);
The parameter shmaddr is the address pointer returned by the SHMAT function, returns 0 when the call succeeds, and returns-1 on failure.
4. The Shmctl function, like the SEMCTL function of the semaphore, is used to control shared memory, and its prototype is as follows:
int shmctl (intintstruct shmid_ds *buf);
The first argument, shm_id, is the shared memory identifier returned by the Shmget function. The second argument, command is the action to take, it can take the following three values: Ipc_stat: Sets the data in the SHMID_DS structure to the current associated value of shared memory, that is, the value of Shmid_ds is overwritten with the current associated value of shared memory. Ipc_set: If the process has sufficient permissions, set the current association value for shared memory to the value given in the SHMID_DS structure Ipc_rmid: Delete the third parameter of the shared memory segment, BUF is a structure pointer to the structure of shared memory mode and access rights. The SHMID_DS structure includes at least the following members:
struct shmid_ds{ uid_t shm_perm.uid; uid_t Shm_perm.gid; mode_t Shm_perm.mode;};
Third, using shared memory for interprocess communication said so much, and then to the actual combat time. The following is a two unrelated process that describes how the process communicates through shared memory. One of the files SHMREAD.C creates the shared memory and reads the information in it, and the other file shmwrite.c writes the data to the shared memory. In order to facilitate the unification of operation and data structure, the same data structure is defined for these two files, which is defined in the file SHMDATA.C. The written in the structure Shared_use_st as a readable or writable flag, not 0: readable, 0 is writable, and text is an in-memory file. The source code for SHMDATA.C is as follows:
#ifndef _shmdata_h_header #define _shmdata_h_header#define TEXT_SZ 2048struct shared_use_st{ int written; // as a flag, not 0: Indicates readable, 0 indicates writable Char TEXT[TEXT_SZ]; // record the text written and read }; #endif
Source file shmread.c The source code is as follows:
#include <unistd.h>#include<stdlib.h>#include<stdio.h>#include<sys/shm.h>#include"shmdata.h"intMain () {intrunning =1;//Flag of whether the program continues to run void*SHM = NULL;//The original first address of the allocated shared memory structShared_use_st *shared;//point to Shm intShmid;//Shared Memory Identifiers//Create shared MemoryShmid = Shmget ((key_t)1234,sizeof(structShared_use_st),0666|ipc_creat); if(Shmid = =-1) {fprintf (stderr,"Shmget failed\n"); Exit (Exit_failure); } //Connect shared memory to the address space of the current processSHM = Shmat (Shmid,0,0); if(SHM = = (void*)-1) {fprintf (stderr,"Shmat failed\n"); Exit (Exit_failure); } printf ("\nmemory attached at%x\n", (int) SHM); //set up shared memoryShared = (structshared_use_st*) SHM; Shared->written =0; while(running)//read the data in shared memory { //There is no process to set data to shared memory to have data readable if(Shared->written! =0) {printf ("You wrote:%s", shared->text); Sleep (rand ()%3); //after reading the data, set written to make the shared memory segment writableShared->written =0; //input End, exit loop (program) if(STRNCMP (Shared->text,"End",3) ==0) Running=0; } Else//There are other processes in writing data that cannot read dataSleep1); } //separating shared memory from the current process if(SHMDT (SHM) = =-1) {fprintf (stderr,"SHMDT failed\n"); Exit (Exit_failure); } //Delete Shared memory if(Shmctl (Shmid, Ipc_rmid,0) == -1) {fprintf (stderr,"Shmctl (ipc_rmid) failed\n"); Exit (Exit_failure); } exit (exit_success);}
Source file shmwrite.c The source code is as follows:
#include <unistd.h>#include<stdlib.h>#include<stdio.h>#include<string.h>#include<sys/shm.h>#include"shmdata.h"intMain () {intrunning =1; void*SHM =NULL; structShared_use_st *shared =NULL; CharBuffer[bufsiz +1];//text to save the input intShmid; //Create shared MemoryShmid = Shmget ((key_t)1234,sizeof(structShared_use_st),0666|ipc_creat); if(Shmid = =-1) {fprintf (stderr,"Shmget failed\n"); Exit (Exit_failure); } //Connect shared memory to the address space of the current processSHM = Shmat (Shmid, (void*)0,0); if(SHM = = (void*)-1) {fprintf (stderr,"Shmat failed\n"); Exit (Exit_failure); } printf ("Memory attached at%x\n", (int) SHM); //set up shared memoryShared = (structshared_use_st*) SHM; while(running)//write data to shared memory { //data has not been read, waiting for data to be read, cannot write text to shared memory while(Shared->written = =1) {Sleep (1); printf ("waiting...\n"); } //writing data to shared memoryprintf"Enter some text:"); Fgets (buffer, bufsiz, stdin); strncpy (Shared-text, buffer, TEXT_SZ); //after writing the data, set the written to make the shared memory segment readableShared->written =1; //input End, exit loop (program) if(STRNCMP (Buffer,"End",3) ==0) Running=0; } //separating shared memory from the current process if(SHMDT (SHM) = =-1) {fprintf (stderr,"SHMDT failed\n"); Exit (Exit_failure); } Sleep (2); Exit (exit_success);}
Then take a look at the results of the run: Analysis: 1, the program Shmread create shared memory, and then connect it to its own address space. A structure Struct_use_st was used at the beginning of shared memory. There is a flag in this structure written, when other processes in the shared memory write to it, the written in shared memory is set to 0, and the program waits. When it is not 0 o'clock, indicating that no process is writing data to the shared memory, the program reads the data from the shared memory and outputs it, then resets the written in shared memory to 0, which allows it to be written to by the shmwrite process. &NBSP;2, program Shmwrite get shared memory and connect to your own address space. Check if the written in shared memory is 0, if not, indicates that the data in shared memory has not been completed, waits for the other process to read, and prompts the user to wait. If the shared memory written is 0, indicating that no other process is reading the shared memory, prompting the user for text, and setting the written in shared memory again to 1, indicating that the write is complete and that other processes can read the shared memory. Iv. Security discussion on the previous example this program is unsafe, and the problem arises when multiple programs are reading and writing data to shared memory at the same time. You might think that you can change the way written is used, for example, only if the written is 0 o'clock the process can write data to the shared memory, and when a process is written not 0 o'clock to read it, and the written is added 1 operation, After reading, the operation is reduced by 1. This is a bit like the ability to read and write locks in file locks. At a glance, it seems to make sense. But this is not an atomic operation, so this practice is not possible. Imagine that when written is 0 o'clock, if there are two processes accessing shared memory at the same time, they will find that written is 0, so two processes write to it, obviously not. When written is 1 o'clock, there are two processes at the same time read the shared memory is also the case, when both processes are read, written becomes -1. to make the program safe to execute, there will be a process synchronization of the system, to ensure that the operation into the critical section is atomic operation. For example, you can use the semaphore described earlier to synchronize processes. Because the operation of the semaphore is atomic. The advantages and disadvantages of using shared memory 1, advantages: we can see that using shared memory for inter-process communication is really very convenient, and the interface of the function is also simple, the data sharing also makes the data between processes do not transfer, but directly access memory, but also speed up the efficiency of the program. At the same time, it does not require a certain parent-child relationship as the process of communicating with anonymous pipelines. 2, Cons: Shared memory does not provide the same, which allows us to use shared memory for inter-process communication, often by other means to synchronize the process between processes.
ipc--Shared Memory