Overview
The shared memory area is the fastest IPC form . Once such memory is mapped to the address space of the process that shares it, these inter-process data transfers no longer involve the kernel, in other words, the process no longer passes the data () to each other by executing system calls into the kernel.
Shared Memory VS. Other IPC forms
Passing data with pipeline/Message Queuing
Passing data with shared memory
After the shared memory is generated, passing the data does not need to go to the Linux kernel , and shared memory allows two or more processes to share a given storage area , and the data does not need to be replicated between multiple processes , so Shared Memory Transfers faster!
mmap Memory Mapping
Map file/device space to shared memory area
#include <sys/mman.h>void *mmap (void *addr, size_t length, int prot, int flags, int fd, off_t offset); int Munmap (voi D *addr, size_t length);
Parameters:
Addr: The starting address to be mapped, usually specified as NULL, allowing the kernel to be automatically selected;
Length: The number of bytes mapped to the process address space;
Prot: Map Area protection method (see below);
Flags: Logo (see below);
FD: File descriptor;
offset: Offsets from the beginning of the file header;
Prot |
Description |
Prot_read |
Page readable |
Prot_write |
Pages can be written |
Proc_exec |
Page executable |
Proc_none |
Page not accessible |
Flags |
Description |
Map_shared |
The change is shared |
Map_private |
The change is private. |
Map_fixed |
Explain the addr parameter exactly, and if you do not specify this parameter, it will be aligned with memory of 4 K size |
Map_anonymous |
Create an anonymous map area that does not involve files |
Mmap return Value:
Success: Returns the starting address of the memory area mapped to;
failure: return map_failed;
Memory Mapping:
(Note: In memory mapping, the page (4K) is used as the unit)
/** Example 1: Write file map maps a file to a process's address space in a readable, writable way, and then writes the content to it **/struct student{Char name[4]; int age;}; int main (int argc,char **argv) {if (argc! = 2) err_quit ("Usage:./main <file-name>"); int fd = open (argv[1], o_creat| o_rdwr| O_trunc, 0666); if (fd = =-1) err_exit ("File Open Error"),//For memory mapping for Space if (Lseek (FD, sizeof (Student) *5-1, seek_set) = = (off_t)-1) Err_exit ("Lseek error"); Write (FD, "", 1); Student *p = (Student *) mmap (NULL, sizeof (Student), prot_write| Prot_read, map_shared, FD, 0); if (p = = map_failed) err_exit ("Mmap error"); At this point: manipulating the file can be like manipulating memory char ch = ' a '; for (int i = 0; i < 5; ++i) {memcpy ((p+i)->name, &ch, 1); (p+i)->age = 20+i; + + ch; } cout << "file initialized!" << Endl; if (Munmap (p, sizeof (Student)) = =-1) err_exit ("Munmap error"); cout << "Process exit ..." << Endl; return 0;}
Map Note points:
1. Memory mapping cannot (and cannot) change the size of the file;
2. The valid address space available for interprocess communication is not entirely limited to the size of the mapping file, but should be based on the size of the memory page (see test below);
3. Once the file is mapped, all access to the mapped area is actually access to the memory area; When you map a region content write file, the content cannot exceed the size of the file.
/** Test: Note that point 2 files are created with 40K content, and write back in 120K content **///Program 1: Write file map int main (int argc,char **argv) {if (argc! = 2) err_quit (" Usage:./main <file-name> "); int fd = open (argv[1], o_creat| o_rdwr| O_trunc, 0666); if (fd = =-1) err_exit ("File open error"); Note: Here our files are actually only 40 bytes if (Lseek (FD, sizeof (Student) *5-1, seek_set) = = (off_t)-1) err_exit ("Lseek error"); Write (FD, "", 1); But we're mapping in 120 bytes Student *p = (Student *) mmap (NULL, sizeof (Student) *15, Prot_wri te| Prot_read, map_shared, FD, 0); if (p = = map_failed) err_exit ("Mmap error"); Writes in a 120-byte manner to char ch = ' a '; for (int i = 0; i < ++i) {memcpy (p+i)->name, &ch, 1); (p+i)->age = 20+i; + + ch; } cout << "file initialized!" << Endl; Unload the memory area in 120 bytes if (Munmap (p, sizeof (Student) *15) = =-1) err_exit ("Munmap error"); Note: To deliberately pause for a moment so that the read program reads the contents of the Shared memory sleep (20); cout << "Process exit ..." << Endl;}
Msync function
int Msync (void *addr, size_t length, int flags);
Perform a synchronous operation on a mapped shared memory
Parameters:
Addr: Memory start address;
Length: Long
Flags: Options
Flags |
Description |
Ms_async |
Performing asynchronous writes |
Ms_sync |
Perform synchronous writes until the kernel has actually written the data to disk before returning |
Ms_invalidate |
Invalidate cached data |
return value:
success: returns 0;
Failure: return-1;
Linux IPC Practice (8)--Shared memory/memory mapping