Introduction to shared memory and MMAP functions in Linux Network Programming

Source: Internet
Author: User

1. Introduction to shared memory

The shared memory zone is the fastest form of IPC. data transmission between these processes no longer involves the kernel. In other words, processes no longer transmit data by executing system calls that enter the kernel.


That is, each process address space has a shared storage ing area. When this area is mapped to the same real physical address space, data exchange can be performed through this area, for example, the shared library is implemented in this way. Many processes use the same function, such as printf. maybe only one copy of printf exists in the real physical address space. o, and all processes are mapped to this printf. o.


Transmit data using pipelines or message queues:


Transmit data using the shared memory:


Even if shared memory is used to transmit data, it reduces the number of times the data enters the kernel and improves the efficiency.


Ii. MMAP Functions

# Include <sys/Mman. h>

Function: maps files or device space to the shared memory area.
Prototype void * MMAP (void * ADDR, size_t Len, int Prot, int flags, int FD, off_t offset );
Parameters
ADDR: the starting address to be mapped. It is usually specified as null to allow the kernel to automatically select
Len: number of bytes mapped to the process address space
Prot: ing protection mode
Flags: Flag
FD: file descriptor
Offset: the offset starting from the file header, which must be an integer multiple of the page size (generally 4 K in 32-bit system structure)
Returned value: the start address of the mapped memory zone is returned successfully;-1 is returned if the operation fails.


Prot parameter values:

Prot_exec indicates that this segment of ing can be executed, for example, ing a shared library

Prot_read indicates the readable part of the ing.

Prot_write indicates the writable section of the ing.

Prot_none indicates that this segment of the ing is not accessible.


There are many flag values. Here we only talk about two. For other values, see MMAP (2)

Map_shared multiple processes share the ing of the same file. One process modifies the mapped memory, and the other process also sees this change.

Map_private multiple processes do not share the ing of the same file. One process modifies the mapped memory, and the other process does not see this change or write it into the file.


Memory ing file:

If MMAP is successful, the first address of the ing is returned. If an error occurs, the constant map_failed is returned. When a process is terminated, the ing memory of the process is automatically removed. You can also call munmap to unbind the ing:

Function: cancels the Ming created by the MMAP function.
Prototype int munmap (void * ADDR, size_t Len );
Parameters
ADDR: memory start address of the ing
Len: number of bytes mapped to the process address space
Return Value: 0 is returned for success;-1 is returned for failure.

Below are two programs to test:

Mmap_write.c

C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# Include <string. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <sys/IPC. h>
# Include <sys/msg. h>
# Include <sys/types. h>
# Include <unistd. h>
# Include <errno. h>
# Include <fcntl. h>
# Include <sys/STAT. h>
# Include <sys/Mman. h>

# Define err_exit (m )\
Do {\
Perror (m );\
Exit (exit_failure );\
} While (0)

Typedef struct Stu
{
Char name [4];
Int age;
} Stu;

Int main (INT argc, char * argv [])
{
If (argc! = 2)
{
Fprintf (stderr, "Usage: % S <File> \ n", argv [0]);
Exit (exit_failure );
}

Int FD;
FD = open (argv [1], o_creat | o_rdwr | o_trunc, 0666 );
If (FD =-1)
Err_exit ("open ");

Lseek (FD, sizeof (Stu) * 5-1, seek_set );
Write (FD, "", 1 );

Stu * P;
P = (Stu *) MMAP (null, sizeof (Stu) * 5, prot_read | prot_write,
Map_shared, FD, 0 );

If (P =-1)
Err_exit ("MMAP ");

Char CH = 'a ';
Int I;
For (I = 0; I <5; I ++)
{
Memcpy (p + I)-> name, & Ch, 1 );
(P + I)-> age = 20 + I;
Ch ++;
}

Printf ("initialize over \ n ");

Munmap (p, sizeof (Stu) * 5 );
Printf ("exit... \ n ");
Return 0;
}

Mmap_read.c

C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# Include <string. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <sys/IPC. h>
# Include <sys/msg. h>
# Include <sys/types. h>
# Include <unistd. h>
# Include <errno. h>
# Include <fcntl. h>
# Include <sys/STAT. h>
# Include <sys/Mman. h>

# Define err_exit (m )\
Do {\
Perror (m );\
Exit (exit_failure );\
} While (0)

Typedef struct Stu
{
Char name [4];
Int age;
} Stu;

Int main (INT argc, char * argv [])
{
If (argc! = 2)
{
Fprintf (stderr, "Usage: % S <File> \ n", argv [0]);
Exit (exit_failure );
}

Int FD;
FD = open (argv [1], o_rdwr );
If (FD =-1)
Err_exit ("open ");

Stu * P;
P = (Stu *) MMAP (null, sizeof (Stu) * 5, prot_read | prot_write,
Map_shared, FD, 0 );

If (P =-1)
Err_exit ("MMAP ");

Int I;
For (I = 0; I <5; I ++)
{
Printf ("name = % s age = % d \ n", (p + I)-> name, (p + I)-> age );
}
Munmap (p, sizeof (Stu) * 5 );
Printf ("exit... \ n ");
Return 0;
}

Run mmap_write first, and then use OD-C to view the file content:

Simba @ Ubuntu :~ /Documents/code/linux_programming/UNP/system_v $./mmap_write Test
Initialize over
Exit...
Simba @ Ubuntu :~ /Documents/code/linux_programming/UNP/system_v $ OD-C Test
0000000 A \ 0 \ 0 \ 0 024 \ 0 \ 0 \ 0 B \ 0 \ 0 \ 0 025 \ 0 \ 0 \ 0 \ 0
0000020 C \ 0 \ 0 \ 0 026 \ 0 \ 0 \ 0 d \ 0 \ 0 \ 0 027 \ 0 \ 0 \ 0 \ 0
0000040 e \ 0 \ 0 \ 0 030 \ 0 \ 0 \ 0 \ 0
0000050 note that the output of OD-C is octal, 0 24 is 20, that is, the memory operation is written into the file. Try mmap_read again. The output is as follows: Simba @ Ubuntu :~ /Documents/code/linux_programming/UNP/system_v $./mmap_read Test
Name = A age = 20
Name = B age = 21
Name = C age = 22
Name = d age = 23
Name = e age = 24
Exit...
Simba @ Ubuntu :~ /Documents/code/linux_programming/UNP/system_v $

Map the file test to the memory again, and then read the file content from the memory.


MMAP programming notes:

1. ing cannot change the file size;
2. The valid address space used for inter-process communication is not completely limited by the size of the mapped file;
3. After a file is mapped, All accesses to the mapped area are actually accesses to the memory area. When the ing area content is written back to a file, the size of the file cannot exceed the size of the file;


For, change 5 in the code after 40 rows in mmap_write.c to 10, that is, the ing memory is larger than the file size, so there is no error in writing, because it is written to the memory, however, when you use od to view the file, it is found that the file is still 40 bytes, that is, only the first five stus are actually written to the file.

For point 2nd, change both mmap_write.c and mmap_read.c to 10 according to the above, and then sleep (10) before the munmap function in mmap_write.c; run mmap_write first, run mmap_read on another terminal:

Simba @ Ubuntu :~ /Documents/code/linux_programming/UNP/system_v $./mmap_read Test
Name = A age = 20
Name = B age = 21
Name = C age = 22
Name = d age = 23
Name = e age = 24
Name = f age = 25
Name = G age = 26
Name = H age = 27
Name = I age = 28
Name = J age = 29
Exit...

That is, when the ing has not been canceled after mmap_write writes to the ing memory area, mmap_read also maps to the test file. The ing areas of the two virtual process address spaces point to the same physical memory, therefore, you can also read the write process's modifications to the memory, but after the process ends, check the test file, which is still 40 bytes. Memory ing is based on the page, which is generally 4 kb. Therefore, there are only 2nd entries. In fact, this is the true embodiment of the shared memory that can communicate between processes.


The last point is similar to the write operation. After a file is mapped to the memory, it is written back to the file. The kernel may also generate a buffer, find a proper time kernel and write it back to the device file. After writing, you can call fsync for synchronization. Similarly, MMAP can call msync for synchronization.


Refer:

Linux C Programming one-stop learning

UNP

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.