利用mmap实现的一个文件拷贝例子
		
				
				/*
				
						
 * gcc -Wall -O3 -o copy_mmap copy_mmap.c
 
				*/
				
						
#include 
				<
				stdio.h
				>
				
						
#include 
				<
				stdlib.h
				>
				
						
#include 
				<
				string
				.h
				>
				  
				/*
				 for memcpy 
				*/
				
						
#include 
				<
				strings.h
				>
				
						
#include 
				<
				sys
				/
				mman.h
				>
				
						
#include 
				<
				sys
				/
				types.h
				>
				
						
#include 
				<
				sys
				/
				stat.h
				>
				
						
#include 
				<
				fcntl.h
				>
				
						
#include 
				<
				unistd.h
				>
				
						
						
				
				#define
				 PERMS 0600
				
						
						
				
				int
				 main ( 
				int
				 argc, 
				char
				 
				*
				 argv[] )
{
    
				int
				          src, dst;
    
				void
				        
				*
				sm, 
				*
				dm; 
    
				struct
				 stat  statbuf;
    
				if
				 ( argc 
				!=
				 
				3
				 )
    {
        fprintf( stderr, 
				"
				 Usage: %s <source> <target>\n
				"
				, argv[
				0
				] );
        exit( EXIT_FAILURE );
    }
    
				if
				 ( ( src 
				=
				 open( argv[
				1
				], O_RDONLY ) ) 
				<
				 
				0
				 )
    {
        perror( 
				"
				open source
				"
				 );
        exit( EXIT_FAILURE );
    }
    
				/*
				 为了完成复制,必须包含读打开,否则mmap()失败 
				*/
				
						
    
				if
				 ( ( dst 
				=
				 open( argv[
				2
				], O_RDWR 
				|
				 O_CREAT 
				|
				 O_TRUNC, PERMS ) ) 
				<
				 
				0
				 )
    {
        perror( 
				"
				open target
				"
				 );
        exit( EXIT_FAILURE );
    }
    
				if
				 ( fstat( src, 
				&
				statbuf ) 
				<
				 
				0
				 )
    {
        perror( 
				"
				fstat source
				"
				 );
        exit( EXIT_FAILURE );
    }
    
				/*
				
						
     * 参看前面man手册中的说明,mmap()不能用于扩展文件长度。所以这里必须事
     * 先扩大目标文件长度,准备一个空架子等待复制。
     
				*/
				
						
    
				if
				 ( lseek( dst, statbuf.st_size 
				-
				 
				1
				, SEEK_SET ) 
				<
				 
				0
				 )
    {
        perror( 
				"
				lseek target
				"
				 );
        exit( EXIT_FAILURE ); 
    } 
    
				if
				 ( write( dst, 
				&
				statbuf, 
				1
				 ) 
				!=
				 
				1
				 )
    {
        perror( 
				"
				write target
				"
				 );
        exit( EXIT_FAILURE );
    } 
    
    
				/*
				 读的时候指定 MAP_PRIVATE 即可 
				*/
				
						
    sm 
				=
				 mmap( 
				0
				, ( size_t )statbuf.st_size, PROT_READ,
               MAP_PRIVATE 
				|
				 MAP_NORESERVE, src, 
				0
				 );
    
				if
				 ( MAP_FAILED 
				==
				 sm )
    {
        perror( 
				"
				mmap source
				"
				 );
        exit( EXIT_FAILURE );
    }
    
				/*
				 这里必须指定 MAP_SHARED 才可能真正改变静态文件 
				*/
				
						
    dm 
				=
				 mmap( 
				0
				, ( size_t )statbuf.st_size, PROT_WRITE,
               MAP_SHARED, dst, 
				0
				 );
    
				if
				 ( MAP_FAILED 
				==
				 dm )
    {
        perror( 
				"
				mmap target
				"
				 );
        exit( EXIT_FAILURE );
    }
    memcpy( dm, sm, ( size_t )statbuf.st_size );
    
				/*
				
						
     * 可以不要这行代码
     *
     * msync( dm, ( size_t )statbuf.st_size, MS_SYNC );
     
				*/
				
						
    
				return
				( EXIT_SUCCESS );
} 
		
		
mmap()好处是处理大文件时速度明显快于标准文件I/O,无论读写,都少了一次用户空间与内核空间之间的复制过程。操作内存还便于设计、优化算法。
文件I/O操作/proc/self/mem不存在页边界对齐的问题,但至少Linux的mmap()的最后一个形参offset并未强制要求页边界对齐,如果提供的值未对齐,系统自动向上舍入到页边界上。malloc()分配得到的地址不见得对齐在页边界上。
        
/proc/self/mem和/dev/kmem不同。root用户打开/dev/kmem就可以在用户空间访问到内核空间的数据,包括偏移0处的数
据,系统提供了这样的支持。显然代码段经过/proc/self/mem可写映射后已经可写,无须mprotect()介入。
参考:
Linux环境进程间通信(五): 共享内存(上) 对mmap的介绍很详细