Shared memory for communication between Linux processes

Source: Internet
Author: User

introduction of Shared memoryShared memory is one of three IPC (inter-process communication) mechanisms. It allows two unrelated processes to access the same logical memory. Shared memory is a very efficient way to pass data between two processes that are in progress. Most of the shared memory implementations, all of the memory shared between different processes is scheduled for the same piece of physical memory.  Shared memory is created by the IPC to create a special address range for the process, which will appear in the address space of the process. Other processes can connect the same piece of shared memory to their own address space. All processes can access addresses in shared memory as if they were allocated by malloc. If a process writes data to shared memory, the changes are immediately visible to any other process that can access the same piece of shared memory.  second, the synchronization of shared memoryShared memory provides an effective way to share and deliver data between multiple processes. but it does not provide a synchronization mechanism,So we usually need to use other mechanisms to synchronize access to shared memory. We typically use shared memory to provide effective access to large chunks of memory and to synchronize access to that memory by passing small messages. There is no automatic mechanism to prevent the second process from starting to read the shared memory until the first process ends its write operation. The synchronization control of shared memory access must be the responsibility of the programmer. Shows how shared memory coexists: The arrows in the diagram show the mapping of the logical address space of each process to the available physical memory. Iii. functions used for shared memory
#include <sys/shm.h>intint  SHMFLG); void *shmat (intconstvoidint  SHMFLG); int shmdt (constvoid *shm_addr); int shmctl (intintstruct shmid_ds *buf);
1. Shmget function This function is used to create shared memory:
int int SHMFLG);
Parameter: Key: Like the semaphore, the program needs to provide a parameter key, which effectively names the shared memory segment. There is a special key value of Ipc_private, which is used to create a shared memory that is only part of the creation process and is not normally used. Size: Specifies the amount of memory that needs to be shared in bytes.         Shmflag: A 9-bit permission flag that works the same as the mode flag used when creating the file. A special bit, defined by ipc_creat, must be a bitwise OR of the permission flags to create a new shared memory segment. Note: A permission flag is useful for shared memory because it allows a process to create shared memory that can be written to by a process owned by the creator of the shared memory, while processes created by other users can read only shared memory. We can use this feature to provide an efficient way to read-only access to the data, and to prevent the data from being modified by other users by putting the data in shared memory and setting its permissions. Return value: Successful creation, returns a nonnegative integer, which is the shared memory identity, or 1 if it fails.

2. Shmat functionWhen you create a shared memory segment for the first time, it cannot be accessed by any process. To initiate access to the memory, you must connect it to the address space of a process. This work is done by the Shmat function:
void *shmat (intconstvoidint shmflg);
Parameter: shm_id: The shared memory identity returned by Shmget.         Shm_add: Specifies the address location of the shared memory connection to the current process. It is usually a null pointer that allows the system to select the address where the shared memory appears.         SHMFLG: is a set of flags.         Its two possible values are: SHM_RND, used in conjunction with Shm_add, to control the address of the shared memory connection. Shm_rdonly, which makes the connected memory read-only return value: If the call succeeds, returns a pointer to the first byte of shared memory, or 1 if it fails. The read and write permissions for shared memory are owned by its owner (the creator of the shared memory), its access rights, and the owner of the current process. Access to shared memory is similar to file access permissions 3. Shmdt detach shared memory from the current process
int shmdt (constvoid *shm_addr);
The address pointer returned by the Shm_addr:shmat. On success, returns 0, when failed, returns-1. Note: Shared memory detach does not delete it, only makes the shared memory unavailable to the current process. 4. Shmctl control functions for shared memory
int shmctl (intintstruct shmid_ds *buf);

The SHMID_DS structure contains at least the following members:

struct Shmid_ds {  uid_t shm_perm.uid;  uid_t Shm_perm.gid;  mode_t Shm_perm.mode;}
Parameters:SHM_ID: Is the shared memory identifier returned by Shmget. Command: Is the action to take, it can take 3 values: Ipc_statSet the data in the SHMID_DS structure to the current associated value of shared memoryIpc_setIf the process has sufficient permissions, set the current association value for shared memory to the value given in the SHMID_DS structureIpc_rmidDelete a shared memory segment BUF: is a pointer that contains the structure of shared memory mode and access rights. Return value: When successful, returns 0, 1 when failed.  Iv. ExamplesA typical consumer-producer program, the first program (consumer) creates a shared memory segment and then displays the data written to it. The second program (producer) connects to an existing shared memory segment and allows us to enter data into it.
Shm_com.h
#define TEXT_SZ 2048struct  shared_use_st {  int  written_by_you;   Char SOME_TEXT[TEXT_SZ];};
When there is data written into this structure, we use the WRITTEN_BY_YOU flag in the structure to inform the consumer. The length of text that needs to be transferred 2K is arbitrary. SHM1.C Consumer Program
#include <unistd.h>#include<stdlib.h>#include<stdio.h>#include<string.h>#include<sys/shm.h>#include"shm_com.h"intMain () {intrunning =1; void*shared_memory = (void*)0; structShared_use_st *Shared_stuff; intShmid; Srand ((unsignedint) Getpid ()); Shmid= Shmget ((key_t)1234,sizeof(structShared_use_st),0666|ipc_creat); if(Shmid = =-1) {fprintf (stderr,"Shmget failed\n");  Exit (Exit_failure); }

Now, let the program have access to this shared memory:

  Shared_memory = Shmat (Shmid, (void *)00);   if (Shared_memory = = (void *)-1)    {"shmat failed\n" );    Exit (exit_failure);  }  printf ("Memory attached at%x\n", (int) shared_memory);
The next part of the program assigns Shared_memory to Shared_stuff, which then outputs the text in Written_by_you. The loop will be executed until the end string is found in written_by_you. Sleep calls forcing the consumer program to stay in the critical area for a while, allowing the producer program to wait:
Shared_stuff = (structShared_use_st *) Shared_memory; Shared_stuff->written_by_you =0;  while(running) {if(shared_stuff->written_by_you) {printf ("You wrote:%s", shared_stuff->some_text); Sleep (rand ()%4);/*Make the other process wait for us!*/Shared_stuff->written_by_you =0; if(STRNCMP (Shared_stuff->some_text, "End",3) ==0) {Running=0; }    }  }

Finally, the shared memory is detached and then deleted:

if (SHMDT (shared_memory) = =-1)   {    "shmdt failed\n");    Exit (exit_failure);  }   if 0) = =-1)    {"shmctl (ipc_rmid) failed\n" );    Exit (exit_failure);  }  Exit (exit_success);}
SHM2.C The producer program enters data through it to the consumer program.
#include <unistd.h>#include<stdlib.h>#include<stdio.h>#include<string.h>#include<sys/shm.h>#include"shm_com.h"intMain () {intrunning =1; void*shared_memory = (void*)0; structShared_use_st *Shared_stuff; CharBuffer[bufsiz]; intShmid; Shmid= Shmget ((key_t)1234,sizeof(structShared_use_st),0666|ipc_creat); if(Shmid = =-1) {fprintf (stderr,"Shmget failed\n");  Exit (Exit_failure); } shared_memory= Shmat (Shmid, (void*)0,0); if(Shared_memory = = (void*)-1) {fprintf (stderr,"Shmat failed\n");  Exit (Exit_failure); } printf ("Memory attached at%x\n", (int) shared_memory); Shared_stuff= (structShared_use_st *) Shared_memory;  while(running) { while(Shared_stuff->written_by_you = =1) {Sleep (1); printf ("Waiting for client...\n"); } printf ("Enter some text:");    Fgets (buffer, bufsiz, stdin); strncpy (Shared_stuff-some_text, buffer, TEXT_SZ); Shared_stuff->written_by_you =1; if(STRNCMP (Buffer,"End",3) ==0) {Running=0; }  }  if(SHMDT (shared_memory) = =-1) {fprintf (stderr,"SHMDT failed\n");  Exit (Exit_failure); } exit (exit_success);}
Run the program and you will see the sample output as shown below:
 $./SHM1 &[ 1 ] 294  memory attached at  40017000  $.  /shm2memory attached at  40017000  enter some text:helloyou wrote:hellowaiting  for  Span style= "COLOR: #000000" > client...waiting  for   client ... Enter some text:you wrote:waiting  for   client...waiting  for   client...waiting  for   client ... Enter some text:endyou wrote:end$  
Program parsing: The consumer program creates a shared memory segment and then connects it to its own address space, and we use a struct shared_use_st at the beginning of shared memory. There is a flag in this structure written_by_you, when there is data written in the shared memory, This flag is set. When this flag is set, the program reads the text from the shared memory, prints it out, and then clears the flag to indicate that the data has been read. We use a special string end to exit the loop. Next, the program detaches the shared memory segment and deletes it. The producer program uses the same key value 1234来 to obtain and connect to the same shared memory segment, and then prompts the user to enter some text. If the flag written_by_you is set, the producer knows that the consumption process has not finished reading the last data, so it continues to wait. When the other process clears the flag, the producer writes the new data and sets the flag. It also uses the string end to terminate and detach shared memory segments. Here are the synchronization flags provided by Written_by_you, which is a very inefficient busy wait (nonstop loop). However, in practical programming, you should use semaphores, or provide a more efficient synchronization mechanism between read and write by passing messages (using pipelines or IPC messages) or by generating signals.

Shared memory for communication between Linux processes

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.