Shared Memory for Process Communication

Source: Internet
Author: User

1. Shared Memory

1.1. Shared Memory

Shared Memory is a very effective way to transmit data between two running processes. The shared memory allows two unrelated processes to access the same logical memory. Because it does not provide a synchronization mechanism, we usually need other mechanisms to synchronize access to the shared memory.

Shared Memory is a special address range created by IPC for a process. It will appear in the address space of the process. Other processes can connect the same shared memory to their own address space. All processes can access the data in the shared memory. If a process writes data to the shared memory, the changes are immediately visible to any other process that can access the same shared memory.

The kernel sets a shmid_ds structure for each shared memory:

Struct shmid_ds {

Struct ipc_perm shm_perm; // see xsi IPC

Size_t shm_segsz; // size of segment in bytes

Pid_t shm_lpid; // PID of last shmop

Pid_t shm_cpid; // PID of creator

Shmatt_t shm_nattch // number of current attaches

Time_t shm_atime; // last-Attach time

Time_t shm_dtime; // last-Detach time

Time_t shm_ctime; // last-Change Time

.

.

.

};

 

To obtain a shared memory identifier, the first function called is shmget.

# Include <sys/SHM. h>

Int shmget (key_t key, size_t size, int flag );

The first parameter key, like the semaphore, is effectively named for the shared memory. The shmget function returns a shared memory identifier, which is used for subsequent shared memory functions. A special key value ipc_private (usually 0) is used to create a shared memory that only belongs to the creation process.

The second parameter size is the length of the shared storage segment (unit: bytes ). If a new segment is being created, the size must be specified. If an existing segment is being referenced, the size is 0. When a new segment is created, the content in the segment is initialized to 0.

The third parameter flag contains nine BITs, which is similar to the file access permission. They can perform bitwise OR operations with the value ipc_creat to create a new shared memory segment. Even if the ipc_creat flag is set, the given key is a key with a semaphore and will not produce errors. Only ipc_creat and ipc_excl are used together to ensure that a new and unique shared memory segment exists. If the shared memory segment exists, an error is returned (errno is set to eexsit ).

If the shared memory is successfully created, shmget returns a non-negative integer (shared memory identifier). If it fails,-1 is returned.

 

The shmctl function performs multiple operations on its shared memory.

# Include <sys/SHM. h>

Int shmget (INT shmid, int cmd, struct shmid_ds * BUF );

The first parameter, shmid, is the shared memory identifier returned by shmget.

The second parameter, CMD, is the operation to be executed. There are five commands:

Ipc_stat obtains the shmid_ds structure of the queue and stores it in the structure pointed to by the Buf.

Ipc_set sets the following four fields in the queue-related structure based on the value pointed by the Buf to the structure: shm_perm.uid, shm_perm.gid, and shm_perm.mode. This command can only be executed by two processes: one is that the valid user ID is SHM _ perm. cuid or SHM _ perm. uid, and the other is a process with super user privileges.

Ipc_rmid deletes the shared memory segment from the system. Because each shared memory segment has a connection count (shm_nattch field in the shmid_ds structure), the memory segment will not be deleted unless the last process in the segment is terminated or detached from the segment. The deletion takes effect immediately, so the shmat cannot be used to connect to the segment. This command can only be executed by two processes: one is that the valid user ID is SHM _ perm. cuid or SHM _ perm. uid, and the other is a process with super user privileges.

Shm_lock locks the shared memory segments in the memory. This command can only be executed by a Super User.

Shm_unlock to unlock the shared memory segment. This command can only be executed by a Super User.

The third parameter Buf is a pointer pointing to the shmid_ds structure containing the shared memory mode and access permissions.

If the request succeeds, shmctl returns 0; if the request fails,-1 is returned.

 

Once a shared memory segment is created, the process can use shmat to connect it to its address space.

# Include <sys/SHM. h>

Int shmat (INT shmid, const void * ADDR, int flag );

The first parameter, shmid, is the shared memory identifier returned by shmget.

The second parameter ADDR specifies the address location in which the shared memory is connected to the current process. It is usually a null pointer that allows the system to select the address that appears in the shared memory.

1) if ADDR is 0, this segment is connected to the first available address selected by the kernel. (Recommended)

2) If ADDR is not 0 and shm_rnd is not specified, this segment is connected to the address specified by ADDR.

3) If ADDR is not 0 and shm_rnd is specified, this segment is connected to the address specified by (ADDR-(ADDR mod Ulus shmlba. The shm_rnd command indicates "Rounding ". Shmlba means "low boundary address multiple", which is always a multiplication of 2. This formula is to take the address down to a multiple of the nearest shmlba.

The fourth parameter flag is a set of flag. It may have two values: shm_rnd (this is used together with shm_addr to control the address of the in-share connection) and shm_rdonly (it makes the connected memory read-only)

If shmat is successfully called, the actual address connected to the segment is returned. If an error occurs,-1 is returned. If the execution is successful, the kernel will add one to the shm_nattch counter in the shmid_ds structure of the shared memory segment.

The read and write permissions of the shared memory are determined by its owner (creator of the shared memory), its access permissions, and the owner of the current process. The exception is that when flag & shm_rdonly is true, the shared memory cannot be written even if its access permission allows write operations.

 

When the operation on the shared memory segment has ended, the shmdt is called to detach the segment.

# Include <sys/SHM. h>

Int shmdt (void * ADDR );

The first parameter is the returned value when shmat was previously called.

If successful, shmdt will reduce the value of the shm_nattch counter in the shmid_ds structure by one.

Note: This does not delete its identifier and its data structure from the system. This identifier still exists until a process calls shmctl (with the command ipc_rmid) to delete it.

 

1.2. Instance

We want to contact these functions after familiarizing ourselves with them. The following are two programs: one is the consumer, one is to create a shared memory segment, and the data written in it is displayed; the other is the producer, connect an existing shared memory segment and allow data input first.

The first program uses a structure named pai_data_seg_s at the beginning of the shared memory. There is a flag in this structure. This flag is set when data is written into the shared memory. When this flag is set, the program reads the text from the shared memory, prints it out, and then clears the mark that the data has been read. The string "end" is received to exit the loop. Finally, the program isolates the shared memory segment and deletes it.

The second program obtains the shared memory identifier, which is linked to the same shared memory segment. Then the user enters the string. If the flag writtenflag is set, you will know that the first program has not read the last data, so you will continue to wait. When this flag is cleared by other processes, new data is written and the flag is set. Write the string "end" to terminate and separate the shared memory segments.

The source program is as follows:

# Include <stdlib. h> <br/> # include <stdio. h> <br/> # include <string. h> <br/> # include <unistd. h> <br/> # include <errno. h> <br/> # include <sys/types. h> <br/> # include <sys/IPC. h> <br/> # include <sys/SHM. h> </P> <p> # define my_sem_proc_id 4 <br/> # define my_proc_path "/user/local/wzhwho" <br/> # define buf_size 2048 </P> <p> typedef struct tag1_dataseg <br/>{< br/> int writtenflag; <br/> char text [buf_size]; </P> <p>} pai_data_seg_s; </P> <p> /******************************** **************************************** * ****** <br/> * shared memory instance (Consumer Program) <br/> * <br/> ******************************* **************************************** * *******/<br/> int main (void) <br/>{ <br/> int running = 1; <br/> void * pai_mem_addr = (void *) 0; <br/> pai_data_seg_s * pai_data; <br/> key_t my_sem_kt; <br/> int shmid; </P> <p> srand (unsigned INT) getpid ()); <br/>/* obtain the shared memory ID */<br/> my_sem_kt = ftok (my_proc_path, my_proc_rcv_id); <br/> shmid = shmget (my_sem_kt, sizeof (pai_data_seg_s), 0666 | ipc_creat); <br/> If (shmid =-1) <br/>{< br/> printf ("failed to shmget share memory/N"); <br/> exit (exit_failure ); <br/>}< br/> pai_mem_addr = shmat (shmid, (void *) 0, 0); <br/> If (pai_mem_addr = (void *)-1) <br/>{< br/> printf ("failed to shmget share memory/N"); <br/> exit (exit_failure ); <br/>}< br/> printf ("memory Attach at 0x % x/N", (INT) pai_mem_addr); <br/> pai_data = (pai_data_seg_s *) pai_mem_addr; <br/> pai_data-> writtenflag = 0; <br/> while (running) <br/>{< br/> If (pai_data-> writtenflag) <br/>{< br/> printf ("You wrote: % s", pai_data-> text); <br/> sleep (RAND () % 4 ); <br/> pai_data-> writtenflag = 0; <br/> If (strncmp (pai_data-> text, "end", 3) = 0) <br/>{< br/> running = 0; <br/>}< br/> If (shmdt (pai_mem_addr) =-1) <br/>{< br/> printf ("failed to shmdt share memory/N"); <br/> exit (exit_failure ); <br/>}< br/> If (shmctl (shmid, ipc_rmid, 0) =-1) <br/>{< br/> printf ("failed to shmctl share memory with ipc_rmid/N"); <br/> exit (exit_failure ); <br/>}< br/> exit (exit_success ); <br/>}</P> <p> /*************************** **************************************** * *********** <br/> * shared memory instance (producer Program) <br/> * <br/> ******************************* **************************************** * *******/<br/> int main (void) <br/>{ <br/> int running = 1; <br/> void * pai_mem_addr = (void *) 0; <br/> pai_data_seg_s * pai_data; <br/> key_t my_sem_kt; <br/> int shmid; <br/> char buf_tmp [buf_size]; </P> <p> srand (unsigned INT) getpid (); <br/>/* obtain the ID of the shared memory */<br/> my_sem_kt = ftok (my_proc_path, my_proc_rcv_id ); <br/> shmid = shmget (my_sem_kt, sizeof (pai_data_seg_s), 0666 | ipc_creat); <br/> If (shmid =-1) <br/>{< br/> printf ("failed to shmget share memory/N"); <br/> exit (exit_failure ); <br/>}< br/> pai_mem_addr = shmat (shmid, (void *) 0, 0); <br/> If (pai_mem_addr = (void *)-1) <br/>{< br/> printf ("failed to shmget share memory/N"); <br/> exit (exit_failure ); <br/>}< br/> printf ("memory Attach at 0x % x/N", (INT) pai_mem_addr); <br/> pai_data = (pai_data_seg_s *) pai_mem_addr; <br/> while (running) <br/> {<br/> while (pai_data-> writtenflag = 1) <br/>{< br/> sleep (1); <br/> printf ("waiting for you... /n "); <br/>}< br/> printf (" Please enter some context: "); <br/> fgets (buf_tmp, buf_size, stdin ); <br/> strncpy (pai_data-> text, buf_tmp, sizeof (pai_data-> text); <br/> pai_data-> writtenflag = 1; <br/> If (strncmp (pai_data-> text, "end", 3) = 0) <br/>{< br/> running = 0; <br/>}</P> <p >}< br/> If (shmdt (mongo_mem_addr) =-1) <br/>{< br/> printf ("failed to shmdt share memory/N"); <br/> exit (exit_failure ); <br/>}< br/> exit (exit_success); <br/>}< br/>

 

 

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.