Shared Memory for Linux inter-process communication

Source: Internet
Author: User

The shared memory zone is the fastest available in the IPC format. Once such a memory zone is mapped to the address space of the process that shares it, the data transfer between these processes will no longer involve the kernel (here, the meaning that does not involve the kernel is: processes no longer transmit data to each other by executing any system calls that enter the kernel ). However, the process that stores or removes information from the shared memory usually requires some form of synchronization. There are multiple synchronous methods, such as semaphores and mutex locks.
 
The following two figures describe the situation where one enters the kernel instead of the kernel when reading and writing messages respectively:

For the system V shared memory area, the kernel maintains the following information structure, which is defined in the header file <sys/SHM. h>:

Struct shmid_ds {

Struct ipc_perm shm_perm;/* operation permission struct */

Size_t shm_segsz;/* segment size */


};

 

With the above knowledge, how to operate on the shared memory is as follows:

Create a new shared memory area or access an existing shared memory area.
# Include <sys/SHM. h>

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

The first parameter of this function is a key value used to identify the shared memory block. Processes that are independent of each other can obtain access to the same shared memory block by specifying the same key. Unfortunately, other programs may also select the same specific value as their own shared memory key value, resulting in a conflict. Using the special constant ipc_private as the key value can ensure that the system creates a new shared memory block. The second parameter of this function specifies the size of the applied memory block. Because these memory blocks are allocated in pages, the size of actually allocated memory blocks will be extended to an integer multiple of the page size. The third parameter is a set of flag, which is based on the bitwise OR operation of a specific constant.
Shmget.

Size specifies the size of the memory area in bytes. When you create a new shared memory partition, you must specify a size value not 0. If the actual operation is to access an existing shared memory area, the size should be 0.
Flag is a combination of read and write permissions. It can also be bitwise OR with ipc_creat or ipc_creat | ipc_excl.
When the actual operation is to create a shared memory area, the memory area is initialized to 0 in size bytes.

After a shared memory area is created or opened by shmget, it is attached to the address space of the calling process by calling shmat.
# Include <sys/SHM. h>

Void * shmat (INT shmid, const void * shmaddr, int flag );

Shmid is the identifier returned by shmget. The shmat return value is the starting address of the specified shared memory zone in the calling process. The rules for determining this address are as follows:

If shmaddr is a null pointer, the system selects the address for the caller. (This is the recommended method)
If shmaddr is a non-null pointer, the returned address depends on whether the caller has specified shm_rnd:
If shm_rnd is not specified, the corresponding shared memory area is attached to the address specified by the shmaddr parameter;
If shm_rnd is specified, the corresponding shared memory area is attached to the address specified by the shmaddr parameter to round down a common shmlba value.
When a process completes the use of the shared memory area, it can call the shmdt to disconnect the memory area.
# Include <sys/SHM. h>

Int shmdt (const void * shmaddr );

When a process is terminated, all the shared memory zones attached to it are automatically disconnected.

Note: This function does not delete the specified shared memory zone.

Shmctl provides multiple operations for a shared memory zone.
# Icnldue <sys/SHM. h>

Int shmctl (INT shmid, int cmd, struct shmid_ds * buff );

This function provides three commands:

Ipc_rmid removes the shared memory area identified by shmid from the system.

Ipc_set sets some members of the shmid_ds structure for the shared memory area described in.

Ipc_stat returns the shmid_ds structure of the specified shared memory area to the caller.

 

The following code uses the shared memory and semaphores to perform operations:

 

Part of the code for the process:
// Create a shared memory Zone

If (shmid1 = shmget (shmkey1, max_sheare_mem_size, ipc_creat | 0666) <0)

{

Perror ("shmget ");

}

// Attach the shared memory area to the address space of the calling Process

If (sharmem = shmat (shmid1, null, 0) <0)

{

Perror ("shmat ");

}

 

While (1)

{

Sem_p (semid1); // semid1 performs P operations to protect the shared area

Memset (buff, 0, max_sheare_mem_size );

Printf ("input ou want to say with you friend! \ N ");

Fgets (buff, max_sheare_mem_size, stdin );

If (strncmp (buff, "quit", 4 ))

{

// Put data into the shared memory area

Strncpy (sharmem, buff, max_sheare_mem_size );

Sem_v (semid2); // semid2 performs the V operation to release protection for the shared area

}

Else

{

Strncpy (sharmem, buff, max_sheare_mem_size );

Sem_v (semid2 );

Break;

}

}

Some code of the receiving process:
While (1)

{

Sem_p (semid2); // semid2 performs P operations to protect the shared area

Memset (buff, 0, max_sheare_mem_size );

Strncpy (buff, sharmem, max_sheare_mem_size); // retrieve data from the shared memory area

Printf ("receive from you friend: % s \ n", buff );

If (! Strncmp (buff, "quit", 4 ))

{

Del_sem (semid1 );

Del_sem (semid2 );

Break;

}

Sem_v (semid1); // semid1 performs the V operation to release protection for the shared area

}

// Delete the shared memory area

If (shmctl (shmid1, ipc_rmid, null) <0)

{

Perror ("shmctl ");

}

// -------------------------------------- Self-written program ------------------------------------

# Include <unistd. h>
# Include <sys/IPC. h>
# Include <sys/SHM. h>
# Include <stdio. h>
# Include <unistd. h>
# Include <string. h> // strcpy ()
# Define key 1234
# Define size 1024

Int main (void)
{
Int shmid;
Char * shmaddr;
Struct shmid_ds Buf;
Shmid = shmget (Key, size, ipc_creat | 0600); // create shared memory
If (Fork () = 0)
{
Shmaddr = (char *) shmat (shmid, 0, 0 );
Strcpy (shmaddr, "Hi! I'm child process! ");
Shmdt (shmaddr );
Return 1;
}
Else
{
Sleep (1 );
Shmctl (shmid, ipc_stat, & BUF);/* Get the shared memory status */
Printf ("shm_segsz = % dbytes \ n", Buf. shm_segsz );
Printf ("shm_cpid = % d \ n", Buf. shm_cpid );
Printf ("shm_lpid = % d \ n", Buf. shm_lpid );
Shmaddr = (char *) shmat (shmid, 0, shm_rdonly );
Printf ("FATHER: % s \ n", shmaddr);/* display shared memory content */
Shmdt (shmaddr );
Shmctl (shmid, ipc_rmid, null);/* Delete shared memory */
}
}

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.