"Linux system Programming" note fourth (iii)

Source: Internet
Author: User
Tags posix

Series of articles directory: http://blog.csdn.net/wylblq/article/details/51841684

4.3 Storage mappings

POSIX provides related calls that allow us to map files into memory, which allows us to easily read file data from memory, modify in-memory data to change the contents of a file, or implement inter-parent interprocess communication.

4.3.1 mmap ()
#include <sys/mman.h>void *mmap(voidlengthintintint fd, off_t offset);

Addr-The memory start address of the developer's recommended mapping file. Generally speaking null let the system self-resolution.
length-The amount of memory used to map, in bytes. Because the smallest addressable unit of memory is a page, the length of less than one page can also occupy a page.
Prot-access to the memory area, with the following parameters, can or operations, note that the access rights to open files are consistent:

Parameters meaning
Prot_exec Page content can be executed
Prot_read Page content can be read
Prot_write Page can be written to
Prot_none Page inaccessible, unreadable, no meaning

Note If the read-write permission for a file is write-only, there is no guarantee that the shared memory function is available because prot_write implies prot_read.
Flags-The behavior of shared memory, common with the following parameters:

The
parameter meaning
map_fixed make With the specified mapping start address, if the memory area specified by the start and Len parameters overlaps the existing mapping space, the overlapping portions are discarded. If the specified start address is not available, the operation will fail. And the start address must fall on the boundary of the page. This parameter can be used to map different files into the same contiguous space
map_shared share the mapping space with all other processes that map this object. Writes to the shared area are equivalent to outputting to a file. The file is not guaranteed to be updated until Msync () is called.
map_private establishes a private mapping of a write-time copy. The write to the memory area does not affect the original file. This flag and map_shared logo are mutually exclusive and can only use one of them. Memory access does not need to be consistent with file access permissions when using this flag
map_anonymous/map_anon Create an anonymous map
map_locked locks the mapped paging in memory, preventing it from being swapped to the swap partition

FD-The file descriptor to map to memory.
Offset-The offsets of the file descriptor, which must be an integer multiple of the page size.
A pointer to the map area is returned after a successful call, and the return of Map_failed,errno on failure is also set, where the error code type is no longer enumerated. When the program tries to access an invalid memory-mapped area, it receives a sigbus signal, and when the program attempts to write to a non-writable region, it receives a SIGSEGV signal.
Shows the possible status of the signal:

2200-4095 of the interval write cannot be synchronized to the file, this area is to ensure that the page alignment free out of the range. 4095-8191 is the length of the map, access to the area will receive a sigbus signal, more than 8192 is an unmapped area, access to the area will receive a SIGSEGV signal.

4.3.1.1 Page size

As mentioned earlier, the offset parameter must be specified as an integer multiple of the page size (the addr parameter is also generally guaranteed to be allocated by the system, and is also page-aligned, the following related calls are so, no longer repeat). For length, a page with less than one page is used, the read multi-occupancy section gets 0, and the write to the multi-occupancy section does not affect the file.
POSIX specifies that the page size can be obtained by sysconf calls:

#include <unistd.h>long sysconf(int name);//返回name对应的值long lPageSize = sysconf(_SC_PAGESIZE);//获取页大小,字节

Linux provides system calls and can also get page sizes:

#include <unistd.h>int getpagesize (void);

In addition, we can use macros to get the page size at compile time:

#include <asm/pages.h>int iPageSize = PAGE_SIZE;

For the portability of binaries, it is recommended that you use the runtime to get the page size, while setting offset to 0,addr is allocated by the system.

4.3.2 Munmap ()

After Mmap () opens the memory map, you can use Munmap () to close it.

#include <sys/mman.h>int munmap (void *addr, size_t len);

Closes the addr start, which is the length of Len bytes of the mapped area.
When we mmap () map a file to memory, the reference count of the file increases by 1, and the reference count of the file is reduced by 1 when our process finishes, executes the EXEC () series function, or shuts down the memory map. To ensure data integrity, you need to call Msync () before Munmap () to write to the hard disk.
The call returns 0 successfully, and the failure returns-1.

Advantages of 4.3.4 Mmap ()

Compared to system calls such as Read ()/write (), mmap () has the following advantages:

    1. Read ()/write () requires the kernel to do read and write operations in the user space memory, mmap () directly manipulate the kernel's page buffers, can avoid a single copy of the data, the advantages of large file operation is obvious
    2. Because of the operation of the mapped memory area, it does not require frequent system calls like Read ()/write ()
    3. Multiple processes map the same file to memory to enable interprocess communication
    4. Moving a read-write location on a file requires only a pointer operation instead of a lseek ()
Defects of 4.3.5 mmap ()

The mapped area must be an integer multiple of the page size, which can easily cause memory waste for mapping small files.
When writing to a file using Mmap (), you need to know in advance the size of the file being written, unlike system calls such as write () to dynamically scale the file size.

4.3.6 Resizing a map
#define _GNU_SOURCE#include <unistd.h>#include <sys/mman.h>void * mremap (voidlong flags);

Adjust the mapping for addr from old_size to new_size. The value of flags can be 0 or mremap_maymove,0 means that the kernel is not allowed to move the map area, and Mremap_maymove indicates that the kernel can move the mapped area according to the actual situation to find a memory area that meets the new_size size requirements. Both the Len and prot parameters are rounded up to an integer multiple of the page size. The call returns the address of the map successfully, and the failure returns map_failed.

4.3.7 changing permissions for a mapped zone
#include <sys/mman.h>int mprotect (constvoidint prot);

Set the Len length, addr start map to the corresponding access permission to prot. This call can modify any memory segment on Linux, not just mmap (), but make sure that addr is page aligned. The value of the prot is consistent with the parameters provided by the mmap ().

4.3.8 synchronizing files using the mapping mechanism

Our modifications to the writable storage mappings are not guaranteed to be synchronized to the file immediately until the synchronous operation is explicitly invoked.

#include <sys/mman.h>int msync (voidint flags);

A map with a length of Len starting with addr is immediately synchronized to memory. The flags take the following meanings:

Take value meaning
Ms_async Msync call will return immediately, not equal to the completion of the update
Ms_sync The Msync call waits until the update is complete and returns
Ms_invalidate After the shared content changes, the other mappings for the file are invalidated, allowing other processes that share the file to regain the latest values.

The call returns 0 successfully, and the failure returns-1.

The following code shows how to write data to a hard disk by storing it in a mapped way:

#include <sys/mman.h>#include <string.h>#include <unistd.h>#include <stdio.h>#include <fcntl.h>#define Wirte_sizeintMain () {intFD = open ("Test.txt", o_creat|    O_RDWR); Ftruncate (FD, wirte_size);//The newly created file must form an empty file, otherwise the written data will be discarded    //The length of the map must be greater than or equal to the scope of the subsequent access, otherwise you will receive the Sigbus signal    void* P =mmap (NULL, Wirte_size, prot_write| Prot_read, map_shared, FD,0);if(p = = map_failed) {Perror ("Mmap");return-1; }memcpy(P,"123",3); Msync (P, wirte_size, Ms_sync);return 0; }

Here's an exercise: Using Mmap () to implement cp a command-like function:

//How to use a.out xxx xxx#include <stdio.h>#include <sys/wait.h>#include <sys/mman.h>#include <unistd.h>#include <string.h>#include <fcntl.h>#include <sys/stat.h>//using storage mapping to implement CP command functionintMainintargcChar*argv[]) {if(ARGC <3)    {printf("Please start as ' a.out srcfile destfile ' \ n");return 0; }intFD = open (argv[1], o_rdonly);if(FD <0) {perror ("Open");return-1; }//file exists without overwriting    /*if (Access (argv[2], F_OK)! =-1) {printf ("Change a destfile name\n");    return 0; }*/    structStat buf; Fstat (FD, &AMP;BUF);printf("File size:%ld\n", buf.st_size);//cannot be used with creat because creat open file mode is write-only and cannot mate with mmap. That's what I said. Mmap can only be combined with file descriptors with Read permissions    //int fddest = creat (argv[2], s_irwxu);    intfddest = open (argv[2], o_rdwr| O_creat, S_irwxu);if(Fddest <0) {perror ("Creat"); }if(Ftruncate (Fddest, buf.st_size) <0) {perror ("Ftruncate");return 0; }Char* s = (Char*) mmap (NULL, Buf.st_size, prot_write| Prot_read, Map_private, FD,0);if(s = = map_failed) {Perror ("Mmap1");return 0; }Char* d = (Char*) mmap (NULL, Buf.st_size, Prot_write, map_shared, Fddest,0);if(d = = map_failed) {Perror ("MMAP2");return 0; }memcpy(d, S, buf.st_size);if(Msync (d, Buf.st_size, Ms_async) <0) {perror ("Mmap");return 0; }return 0;}

"Linux system Programming" note fourth (iii)

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.