shared memory of the Linux IPCTags: linuxrandomnull work2011-08-25 11:52 4123 People read comments (0) favorite reports Classification:Linux (3)reading notes (3)
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Brief introduction
Shared memory is one of the simplest ways to communicate between Linux processes. With shared memory, different processes can read and write to the same block of memory. This is the most efficient and fastest way to communicate between processes because all processes have access to shared memory as if they were accessing their own memory space without additional system calls or kernel operations, while avoiding redundant memory copies.
This maximum freedom also presents a disadvantage to shared memory: The kernel does not provide any synchronization mechanisms for shared memory access, such as writing to the same address of shared memory at the same time, then the data that is written overwrites the previous data. Therefore, the use of shared memory generally also requires the use of other IPC mechanisms (such as semaphores) for read-write synchronization and mutual exclusion.
Basic principle
Understanding the Linux memory management mechanism makes it easy to know how the shared memory works. As you know, the kernel management of memory is in pages (page), the General Linux under a page size is 4k. The virtual address space of the program itself is linear, so the kernel manages the mapping of the process from the virtual address space to the corresponding page. After creating the shared memory space, the kernel maps different process virtual addresses to the same page: So in different processes, access to the memory address where the shared memory resides is ultimately mapped to the same page. Demonstrates the working mechanism of shared memory:
How to use
The use of shared memory can be divided between create-and-connect, use-and-detach, and destroy these steps.
The creation of shared memory uses the Shmget function (Shared memories GET) function, using the following method:
[CPP]View PlainCopy
- int segment_id = Shmget (Shm_key, GetPageSize (), Ipc_creat | S_IRUSR | S_iwuser);
Shmget creates a shared memory space of size page_size based on Shm_key, and Parameter 3 is a series of creation parameters. If Shm_key has already been created, using the Shm_key returns an ID that can be connected to that to create the shared memory.
After creation, in order for the shared memory to be used by the current process, the connection operation must be followed. Using the function Shmat (shared memory ATtach), the parameters are passed in with the shared ID returned by Shmget:
[CPP]View PlainCopy
- Shared_memory = (char*) Shmat (segment_id, 0, 0);
Shmat returns the address pointer mapped to the process virtual address space so that the process accesses the shared memory as if it were accessing a common memory buffer. In the example of the latter two parameters we all pass in 0, with the default connection mode. In fact, the second parameter is the address of the virtual address space of the process you want to connect to, and if you use 0,linux you will choose an appropriate address; The third parameter is the connection option, which can be:
SHM_RND: The memory space pointed to by the second parameter is automatically promoted to an integer multiple of page size, and if you do not know the parameter, you need to control the size of the memory space referred to in the second parameter.
Shm_rdonly: The shared memory is read-only and not writable.
After the shared memory has been used, use the function shmdt (Shared memories DeTach) to connect to the solution. The function takes the memory address returned by Shmat as the parameter. The kernel will automatically destroy the shared memory after each of the last processes that used the shared memory to detach the shared memory. Of course, we'd better be able to explicitly destroy it to avoid unnecessary waste of shared memory resources. The function shmctl (shared memory control) returns and controls the information shared
[CPP]View PlainCopy
- Shmctl (segment_id, Ipc_stat, &shmbuffer);
You can return information about the shared memory and save the information in the SHMID_DS structure that the third parameter points to.
When you pass in Ipc_rmid to the second parameter, shared memory separates the shared memory from the last process that uses the shared memory, and the shared memory is destroyed.
Shmctl There are many other ways to use it and don't repeat it.
Sample Program
In the following example program, a process writes a random number to the shared memory every second, and the B process reads the number from that shared memory every second.
[CPP]View PlainCopy
- /*
- * A.C
- * Write a random number between 0 and 999 to the SHM every 1 second
- */
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/shm.h>
- #include <stdlib.h>
- #include <error.h>
- int main () {
- int shm_id;
- int *share;
- int num;
- Srand (Time (NULL));
- shm_id = Shmget (1234, GetPageSize (), ipc_creat);
- if (shm_id = =-1) {
- Perror ("Shmget ()");
- }
- Share = (int *) Shmat (shm_id, 0, 0);
- While (1) {
- num = random ()% 1000;
- *share = num;
- printf ("Write a random number%d\n", num);
- Sleep (1);
- }
- return 0;
- }
[CPP]View PlainCopy
- /*
- * B.C
- * Read from the SHM every 1 second
- */
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/shm.h>
- #include <stdlib.h>
- #include <error.h>
- int main () {
- int shm_id;
- int *share;
- shm_id = Shmget (1234, GetPageSize (), ipc_creat);
- if (shm_id = =-1) {
- Perror ("Shmget ()");
- }
- Share = (int *) Shmat (shm_id, 0, 0);
- While (1) {
- Sleep (1);
- printf ("%d\n", *share);
- }
- return 0;
- }
Run program A and program B, respectively, with the following results
Ps
As mentioned earlier, shared memory is simple and efficient, but lacks synchronization mechanisms, so it is generally necessary to work with other IPC mechanisms. Otherwise it will definitely bring synchronization problems.
Shared memory C Case of Linux IPC