From: http://blog.csdn.net/dancing999/archive/2008/01/13/2042473.aspx
Example 1: two processes map common files to implement shared memory communication
Example 1 contains two subprograms: map_normalfile1.c and map_normalfile2.c. Compile two programs. The executable files are map_normalfile1 and map_normalfile2. The two programs use the command line parameter to specify the same file to implement inter-process communication in the Memory sharing mode. Map_normalfile2 tries to open a common file specified by the command line parameter, map the file to the address space of the process, and write the mapped address space. Map_normalfile1 maps the file specified by the command line parameter to the process address space, and then performs read operations on the mapped address space. In this way, two processes use the command line parameter to specify the same file to implement inter-process communication in the Memory sharing mode.
The following are two program codes:
/* ------------- Map_normalfile2.c Write File ----------- */<br/> # include <sys/Mman. h> <br/> # include <sys/types. h> <br/> # include <fcntl. h> <br/> # include <unistd. h> <br/> typedef struct {<br/> char name [4]; <br/> int age; <br/>} people; </P> <p> main (INT argc, char ** argv) // map a normal file as shared mem: <br/>{< br/> int FD, i; <br/> People * p_map; <br/> char temp; <br/> FD = open (argv [1], o_creat | o_rdwr | o_trunc, 00777 ); <br/> lseek (FD, sizeof (people) * 5-1, seek_set); <br/> write (FD, "", 1 ); <br/> p_map = (People *) MMAP (null, sizeof (people) * 10, prot_read | prot_write, map_shared, FD, 0 ); <br/> close (FD); <br/> temp = 'a'; <br/> for (I = 0; I <10; I ++) <br/> {<br/> temp + = 1; <br/> memcpy (* (p_map + I )). name, & temp, 2); <br/> (* (p_map + I )). age = 20 + I; <br/>}</P> <p> printf ("initialize over/N"); <br/> sleep (10 ); <br/> munmap (p_map, sizeof (people) * 10); <br/> printf ("umap OK/N "); <br/>}</P> <p>/* ------------- map_normalfile2.c Read File ----------- */<br/> # include <sys/Mman. h> <br/> # include <sys/types. h> <br/> # include <fcntl. h> <br/> # include <unistd. h> </P> <p> typedef struct {<br/> char name [4]; <br/> int age; <br/>} people; </P> <p> main (INT argc, char ** argv) // map a normal file as shared mem: <br/>{< br/> int FD, i; <br/> People * p_map; <br/> FD = open (argv [1], o_creat | o_rdwr, 00777); <br/> p_map = (People *) MMAP (null, sizeof (people) * 10, prot_read | prot_write, map_shared, FD, 0); <br/> for (I = 0; I <10; I ++) <br/> {<br/> printf ("Name: % s age % d;/N", (* (p_map + I )). name, (* (p_map + I )). age); <br/>}< br/> munmap (p_map, sizeof (people) * 10); <br/>}
Map_normalfile1.c first defines a people data structure (the data structure is used here because the data in the shared memory area is usually in a fixed format, which is determined by the communication processes, the structure is generally representative ). Map_normfile1 first open or create a file, and set the file length to 5 people structure sizes. Then, 10 people structures are set starting from the return address of MMAP. Then, the process sleep for 10 seconds, wait for other processes to map the same file, and finally unmap.
Map_normfile2.c is just a simple ing of a file. It reads 10 people structures from the address returned by MMAP () in the format of people data structure, outputs the read values, and unmaps them.
After compiling the two programs into the executable files map_normalfile1 and map_normalfile2, run./map_normalfile2/tmp/test_shm on one terminal. The output result is as follows:
Initialize over
Umap OK
Run map_normalfile2/tmp/test_shm on another terminal after map_normalfile1 outputs initialize over and umap OK (to save space, the output result is a result after sorting ):
Name: B age 20; Name: C age 21; Name: d age 22; Name: e age 23; Name: F age 24;
Name: G age 25; Name: H age 26; Name: I age 27; Name: J age 28; Name: K age 29;
After map_normalfile1 outputs umap OK, run map_normalfile2 and output the following results:
Name: B age 20; Name: C age 21; Name: d age 22; Name: e age 23; Name: F age 24;
Name: age 0; Name: age 0; Name: age 0; Name: age 0; Name: age 0;
Conclusion drawn from the running results of the program
1. The content length of the finally mapped file will not exceed the initial size of the file, that is, the ing cannot change the file size;
2. The size of the valid address space that can be used for process communication is generally limited by the size of the mapped file, but not completely limited by the file size. The opened file is truncated to 5 people structure sizes, and 10 people data structures are initialized in map_normalfile1. when appropriate (map_normalfile1 outputs initialize over and before umap OK) when map_normalfile2 is called, map_normalfile2 will output the values of all 10 people structures, which will be discussed in detail later. Note: in Linux, the memory protection is based on pages. Even if the mapped file has only one byte size, the kernel will allocate a page size memory for the ing. When the size of the mapped file is smaller than the size of a page, the process can access the page size starting with the return address of MMAP () without errors. However, if you access an address space other than a page, an error occurs, which will be further described later. Therefore, the size of the valid address space used for inter-process communication does not exceed the file size and the sum of the size of a page.
3. Once a file is mapped, the process that calls MMAP () accesses the returned address to a memory area, which is temporarily out of the influence of files on the disk. All operations on the address space returned by MMAP () are only meaningful in the memory. Only after munmap () is called or msync () is the corresponding content in the memory written back to the disk file, the size of the file cannot exceed the size of the file.
Example 2: the parent-child process achieves shared memory through anonymous ing
# Include <sys/Mman. h> <br/> # include <sys/types. h> <br/> # include <fcntl. h> <br/> # include <unistd. h> <br/> typedef struct {<br/> char name [4]; <br/> int age; <br/>} people; </P> <p> main (INT argc, char ** argv) <br/>{< br/> int I; <br/> People * p_map; <br/> char temp; <br/> p_map = (People *) MMAP (null, sizeof (people) * 10, prot_read | prot_write, map_shared | map_anonymous,-1, 0 ); <br/> If (Fork () = 0) <br/>{< br/> sleep (2); <Br/> for (I = 0; I <5; I ++) <br/> printf ("child read: the % d people's age is % d/N ", I + 1, (* (p_map + I )). age); <br/> (* p_map ). age = 100; <br/> munmap (p_map, sizeof (people) * 10); // In fact, The ing is automatically removed when the process is terminated. <Br/> exit (); <br/>}< br/> temp = 'a'; <br/> for (I = 0; I <5; I ++) <br/>{< br/> temp + = 1; <br/> memcpy (* (p_map + I )). name, & temp, 2); <br/> (* (p_map + I )). age = 20 + I; <br/>}< br/> sleep (5); <br/> printf ("parent read: The first people, s age is % d/N ", (* p_map ). age); <br/> printf ("umap/N"); <br/> munmap (p_map, sizeof (people) * 10 ); <br/> printf ("umap OK/N"); <br/>}
Measure the test taker's knowledge about the output result of the program and the anonymous memory shared by the parent and child processes:
Child read: The 1 People's age is 20
Child read: The 2 people's age is 21
Child read: The 3 people's age is 22
Child read: The 4 people's age is 23
Child read: The 5 people's age is 24
Parent read: The First People, s age is 100
Umap
Umap OK