linux mmap映射区

本文探讨了内存映射文件技术在提高大文件读写效率的应用,通过对比传统文件读写方法,展示了如何利用内存映射来显著提升大文件拷贝速度,包括具体的C语言实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


主要用途如下:
1、将一个普通文件映射到内存中,通常在需要对文件进行频繁读写时使用,这样用内存读写取代I/O读写,以获得较高的性能;
2、将特殊文件进行匿名内存映射,可以为关联进程提供共享内存空间(fork 之后,在子进程中操作描述符而不用创建)
3、为无关联的进程提供共享内存空间,一般也是将一个普通文件映射到内存中(进程通信)
4、大文件的读取

 待续: https://www.cnblogs.com/alantu2018/p/8506381.html

大文件拷贝例子:
1、用内存映射的方法

// file my_copy.c

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>

#define BUF_SIZE (4096*1000) // sysconf(_SC_PAGE_SIZE) 的整数倍
// 线程栈 的大小默认是 8M + 4K(溢出保护检测区域),所以超过这个大小就会报错
 
int main(int argc,char *argv[])
{
	int fd_r,fd_w;
	char * p_w,*p_r;

	unsigned long int length_r,length_w,len = 0;
	unsigned long int off= 0;
	clock_t times = 0;
	
	assert(argc == 3);
	fd_r = open(argv[1],O_RDWR);
	assert(fd_r);
	fd_w = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0644);
	assert(fd_w);
	
	length_r = lseek(fd_r,0,SEEK_END);
	length_w = lseek(fd_w,length_r - 1,SEEK_CUR);
	
	write(fd_w,"",1); //防止 bus error
	lseek(fd_w,0,SEEK_SET);
	lseek(fd_r,0,SEEK_SET);

	printf("page size = %d \n", _SC_PAGE_SIZE);
	printf("sysconf(_SC_PAGE_SIZE) size = %d \n\n", (int)sysconf(_SC_PAGE_SIZE));

	while(1)
	{
		if((off + BUF_SIZE) >= length_r)
		{
			len = length_r - off;
			p_r = mmap(NULL,BUF_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,fd_r,off);
			p_w = mmap(NULL,BUF_SIZE,PROT_WRITE,MAP_SHARED,fd_w,off);
			memcpy(p_w,p_r,len);
			munmap(p_r,BUF_SIZE);
			munmap(p_w,BUF_SIZE);
			break;
		}
		else
		{
			len = BUF_SIZE;
		}

		p_r = mmap(NULL,BUF_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,fd_r,off);
		p_w = mmap(NULL,BUF_SIZE,PROT_WRITE,MAP_SHARED,fd_w,off);
		memcpy(p_w,p_r,len);
		munmap(p_r,BUF_SIZE);
		munmap(p_w,BUF_SIZE);
		
		off += len;
	}
	
	times = clock();
	printf("%lu \n", times);
	
	close(fd_r);
	close(fd_w);

	times = clock();
	printf("%lu \n", times);
	
	return 0;
}

//gcc -o my_copy my_copy.c
// ./my_copy file1 file2
// cmp -b file1 file2 
// 一样的话,无输出

2、不用内存映射的方法
  试了一下,2G的文件 速度差不多,有时候反而比上面快一些


//#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
 
#define BUF_SIZE (4096*1000)

char buf[BUF_SIZE];

int main(int argc,char *argv[])
{
	//int fd_r,fd_w;

	FILE *fd_r = NULL;
	FILE *fd_w = NULL;
	size_t read_len = 0;
	
	clock_t times = 0;

	long unsigned int length_r,length_w,len = 0;
	long unsigned int off= 0;
	assert(argc == 3);
	//fd_r = open(argv[1],O_RDWR);

	fd_r=fopen(argv[1],"r");
	assert(fd_r);

	fd_w=fopen(argv[2],"wr");
	assert(fd_w);

	fseek(fd_r,0,SEEK_END);
	length_r = ftell(fd_r);
  fseek(fd_r,0,SEEK_SET); 

	printf("read  file len: %lu \n", length_r);

	while(1)
	{
		memset(buf, 0, BUF_SIZE);
		read_len=fread(buf, 1, BUF_SIZE, fd_r);
		if(read_len > 0)
			fwrite(buf, read_len, 1, fd_w);

		if(read_len < BUF_SIZE)
		{
			off += read_len;
			break;
		}
		off += BUF_SIZE;
	}

	printf("write file len: %lu \n", off);
  times = clock();
	printf("write over cost time: %lu \n", times);

	fclose(fd_r);
	fclose(fd_w);
	times = clock();
	printf("all over cost time: %lu \n", times);

	return 0;
}

。。。
 

参照: https://blog.youkuaiyun.com/nocodelife/article/details/8647499

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值