1) concept:
1) both Linux and all UNIX operating systems allow shared storage space between applications through the sharing.
2) There are two basic API functions used to share memory between processes: System V and POSIX.
3) These two types of functions use the same principle. The core idea is that any memory to be shared must be allocated through display.
4) because all processes share the same memory, the shared memory has the highest efficiency among various inter-process communication methods.
5) The kernel does not synchronize access to the shared memory. Therefore, you must provide your own synchronization measures. For example, before writing data, other processes are not allowed to read and write the data. here we use wait to solve this problem.
2) POSIX shared memory API
1) The shm_open and shm_unlink functions are very similar to the open and unlink system calls provided by common files.
2) If you want to write a portable program, shm_open and shm_unlink are the best choices.
3) shm_open: Create a new shared area or attach it to an existing shared area. The area is identified by its name. The function returns the descriptor of each file.
4) shm_unlink: similar to the unlink system call to operate on the file, it is not released until all processes no longer reference the memory zone.
5) MMAP: used to map a file to a memory zone. The file descriptor returned by the shm_open function is also used.
6) munmap: Used to release the memory region mapped by MMAP.
7) msync: synchronously accesses a ing area and writes the cached data back to the physical memory so that other processes can listen for these changes.
Source code 1:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <sys/file.h>#include <sys/mman.h>#include <sys/wait.h>void error_out(const char *msg){perror(msg);exit(EXIT_FAILURE);}int main (int argc, char *argv[]){int r;const char *memname = "/mymem";const size_t region_size = sysconf(_SC_PAGE_SIZE);int fd = shm_open(memname, O_CREAT|O_TRUNC|O_RDWR, 0666);if (fd == -1)error_out("shm_open");r = ftruncate(fd, region_size);if (r != 0)error_out("ftruncate");void *ptr = mmap(0, region_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);if (ptr == MAP_FAILED)error_out("MMAP");close(fd);pid_t pid = fork();if (pid == 0){u_long *d = (u_long *)ptr;*d = 0xdeadbeef;exit(0);}else{int status;waitpid(pid, &status, 0);printf("child wrote %#lx\n", *(u_long *)ptr);}sleep(50);r = munmap(ptr, region_size);if (r != 0)error_out("munmap");r = shm_unlink(memname);if (r != 0)error_out("shm_unlink");return 0;}Compile:
Gcc-O postix-SHM postix-shm.c-LRT
./Postix-SHM
Child wrote 0 xdeadbeef
Wait 50 seconds until the program exits.
Program Analysis:
1) The program executes the shm_open function to create a shared memory area. The mymem file is created in/dev/SHM.
2) use the ftruncate function to change the size of the shared memory created by shm_open to the page size (sysconf (_ SC _page_size). If the ftruncate function is not executed, a bus error is reported.
3) map the created mymem file to the memory using the MMAP function.
4) A subprocess is derived from fork, and the shared zone ing is inherited by calling fork.
5) The program uses the wait system call to keep the synchronization between the parent process and the child process.
6) Non-parent-child processes can also communicate in the shared memory area.
The implementation of Linux shared memory depends on the shared memory file system. This file system is usually loaded in/dev/SHM. When you call the shm_open system function, the mymem file is generated in the/dev/SHM/directory.
Then the program calls shm_unlink to delete mymem. What if the mount point/dev/SHM is unmounted here?
View partition information
DF-H
Filesystem size used avail use % mounted on
/Dev/sda1 19G 973 M 17G 6%/
Tmpfs 253 M 0 253 M 0%/lib/init/RW
Udev 10 m 88 K 10 m 1%/dev
Tmpfs 253 M 0 253 M 0%/dev/SHM
Uninstall/dev/SHM
Umount/dev/SHM/
./POSIX-SHM &
Child wrote 0 xdeadbeef
[1] 15476
Ls-L/dev/SHM/mymem
-RW-r -- 1 Root 4096/dev/SHM/mymem
We can see that shm_open only creates a file under/dev/SHM, regardless of whether/dev/SHM is a partition mounted with tmpfs.
What if I delete/dev/SHM?
Rmdir/dev/SHM
Execute POSIX-SHM again
./POSIX-SHM &
Child wrote 0 xdeadbeef
In this case, the program cannot find/dev/SHM, and the shared memory file is created in the/dev/directory.
Ls-L/dev/mymem
-RW-r -- 1 Root 4096/dev/mymem
3) System V shared memory API
1) System v api is widely used in X Windows and its extended versions. Many x applications also use it.
2) shmget: Create a new shared area or attach it to an existing shared area (same as shm_open ).
3) shmat: used to map a file to the memory area (same as MMAP ).
4) shmdt: Used to release the mapped memory area (same as munmap)
5) shmctl: disconnect multiple users from the shared area (same as shm_unlink)
Source program 2:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <sys/ipc.h>#include <sys/shm.h>#include <sys/wait.h>void error_out(const char *msg){perror(msg);exit(EXIT_FAILURE);}int main (int argc, char *argv[]){key_t mykey = 12345678;const size_t region_size = sysconf(_SC_PAGE_SIZE);int smid = shmget(mykey, region_size, IPC_CREAT|0666);if(smid == -1)error_out("shmget");void *ptr;ptr = shmat(smid, NULL, 0);if (ptr == (void *) -1)error_out("shmat");pid_t pid = fork();if (pid == 0){u_long *d = (u_long *)ptr;*d = 0xdeadbeef;exit(0);}else{int status;waitpid(pid, &status, 0);printf("child wrote %#lx\n", *(u_long *)ptr);}sleep(30);int r = shmdt(ptr);if (r == -1)error_out("shmdt");r = shmctl(smid, IPC_RMID, NULL);if (r == -1)error_out("shmdt");return 0;}Compile GCC sysv-shm.c-O sysv-SHM-LRT
./Sysv-SHM
Child wrote 0 xdeadbeef
Program Analysis:
1) The key_t variable used by the shmget function is functionally equivalent to the file name used by shm_open, And the SMID returned by shmget is functionally equivalent to the file descriptor returned by shm_open.
2) Unlike the memory zone created by posix api, the memory zone created by System v api is invisible in any file system.
3) You can use IPCS to Manage System v api shared memory.