Linux C下的内存映射函数

前面有一篇文章 内存映射文件 给出了windows环境下,内存映射文件的例子。其实在Linux环境下,针对C语言也有相应的内存映射函数。使用内存映射函数可以提高文件读写的速度,在Linux环境下,利用mmap函数可以将指定的文件映射到内存区域中,通过对该内存区域的操作即可以实现对该文件的操作。

mmap函数的调用格式如下:

#include<sys/mman.h>
void *mmap(void *addr,size_t length,int prot,int flags, int fd,off_t offset);

该函数如果调用成功则返回文件映射区间的实际地址,否则返回MAP_FAILED(-1)。

其中,参数addr指定内存映射区域的起始位置,通常将其值设置为0,代表让系统自动选定地址,对应成功后该地址会返回;length表示映射的字节数;port表示映射区域的保护方式,有四种类型,PORT_READ、PORT_WRITE、PORT_EXEC、PORT_NONE分别表示映射区间可读、可写、可执行、不可访问;flags标识影响映射区间的相应属性,有6个取值,分别为MAP_FIXED、MAP_SHARED、MAP_PRIVATE、MAP_ANONYMOUS、MAP_DENYWRITE、MAP_LOCKED;fd标识被映射的文件描述符,该值通常是open函数的返回值;offset标识映射字节在文件中的偏移量。

下面给出一个例子,使用mmap将etc/passwd文件映射到内存区域,然后进行相应的输出操作。

#include<sys/type.h>
#include<sys/stat.h>
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/mman.h>
int main()
{
	int fd;
	void *start;
	struct stat sb;
	fd=open("/etc/passwd",O_RDONLY);
	fstat(fd,&sb);
	start=mmap(NULL,sb.st_size,PORT_READ,MAP_PRIVATE,fd,0);
	if(start==MAP_FAILED)
		return 0;
	printf("%s",start);
	munmap(start,sb.st_size);//解除映射 
	close(fd); 
}
编译执行结果如下:

wiki百科下面也有一个很好的例子。

#include <sys/types.h>
#include <sys/mman.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* Does not work on OS X, as you can't mmap over /dev/zero */
int main(void)
{
        const char str1[] = "string 1";
        const char str2[] = "string 2";
        int parpid = getpid(), childpid;
        int fd = -1;
        char *anon, *zero;

        if ((fd = open("/dev/zero", O_RDWR, 0)) == -1)
                err(1, "open");

        anon = (char*)mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
        zero = (char*)mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0);

        if (anon == MAP_FAILED || zero == MAP_FAILED)
                errx(1, "either mmap");

        strcpy(anon, str1);
        strcpy(zero, str1);

        printf("PID %d:\tanonymous %s, zero-backed %s\n", parpid, anon, zero);
        switch ((childpid = fork())) {
        case -1:
                err(1, "fork");
                /* NOTREACHED */
        case 0:
                childpid = getpid();
                printf("PID %d:\tanonymous %s, zero-backed %s\n", childpid, anon, zero);
                sleep(3);

                printf("PID %d:\tanonymous %s, zero-backed %s\n", childpid, anon, zero);
                munmap(anon, 4096);
                munmap(zero, 4096);
                close(fd);
                return EXIT_SUCCESS;
        }

        sleep(2);
        strcpy(anon, str2);
        strcpy(zero, str2);

        printf("PID %d:\tanonymous %s, zero-backed %s\n", parpid, anon, zero);
        munmap(anon, 4096);
        munmap(zero, 4096);
        close(fd);
        return EXIT_SUCCESS;
}


tech上有篇文章也是介绍mmap,写得也不错

http://linux.about.com/library/cmd/blcmdl2_mmap.htm

参考

Wiki百科mmap

https://en.wikipedia.org/wiki/Mmap

http://linux.about.com/library/cmd/blcmdl2_mmap.htm

百度百科mmap

http://baike.baidu.com/link?url=yMI8iz1KHFR0CPujxSdFFCWUykvd0QaWJcKteTaaqIeTJEcSdIkSs3Rd-9wVsE6xIvYJc7monFiXT8qHwqlrw_


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值