Java教程

Ubuntu下基于mmap映射区的多进程拷贝(运行成功)

本文主要是介绍Ubuntu下基于mmap映射区的多进程拷贝(运行成功),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

实现文件多进程拷贝。

**假设有一个超大文件,需对其完成拷贝工作。为提高效率,可采用多进程并行拷贝的方法来实现。假设文件大小为len,共有n个进程对该文件进行拷贝。那每个进程拷贝的字节数应为len/n。但未必一定能整除,我们可以选择让最后一个进程负责剩余部分拷贝工作。可使用len % (len/n)将剩余部分大小求出。

为降低实现复杂度,可选用mmap来实现源、目标文件的映射,通过指针操作内存地址,设置每个进程拷贝的起始、结束位置。借助MAP_SHARED选项将内存中所做的修改反映到物理磁盘上。**

在这里插入图片描述
大体意思是将一个文件里的内容拷贝到另一个文件,使用多进程的方式加快效率。

#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/mman.h>
#include<string.h>

int main(int argc,char* argv[])
{
	//映射空间指针
	char* p = NULL;
	char* q = NULL;
	if(argc < 3)
	{
		perror("./a.out src_file dst_file\n");
		exit(1);
	}

	//1.指定创建子进程的个数
	int N = 4;
	
	//2.打开源文件
	int fd1 = open(argv[1],O_RDWR);
	if(fd1 < 0)
	{
		perror("fd1 open error");
		exit(1);
	}

	//3.打开目标文件,没有则创建
	int fd2 = open(argv[2],O_CREAT|O_RDWR|O_TRUNC,0644);
	if(fd2 < 0)
	{
		perror("fd2 open error");
		exit(1);
	}

	//4.获取文件大小
	struct stat statbuf;
	int size;
	stat(argv[1],&statbuf);
	size = statbuf.st_size;

	//5.根据文件大小扩展目标文件
	int len = truncate(argv[2],size);
	if(len < 0)
	{
		perror("truncate error");
		exit(1);
	}

	//6.为源文件创建映射
	p = (char*)mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_SHARED,fd1,0);
	if(p == MAP_FAILED)
	{
		perror("fd1 mmap error");
		exit(1);
	}

	//7.为目标文件创建映射
	q = (char*)mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_SHARED,fd2,0);
	if(q == MAP_FAILED)
	{
		perror("fd2 mmap error");
		exit(1);
	}
	close(fd1);
	close(fd2);

	//8.求出每个子进程应该拷贝的字节数
	//每个子进程整除的字节数
	int a = size / N;
	//剩余的字节数
	int b = size % N;

	//9.创建N个子进程
	pid_t pid;
	int i;

	for(i = 0;i < N;i++)
	{
		pid = fork();
		if(pid == 0)
		{
			break;
		}
		else if(pid < 0)
		{
			perror("fokr error");
			exit(1);
		}
	}

	//10.子进程完成分块拷贝(注意最后一个子进程拷贝的起始位置)
	if(i == N)
	{
		for(i = 0;i < N;i++)
		{
			wait(NULL);
		}
	}
	else if(i == (N-1))//最后一个子进程
	{
		memcpy(q+i*a,p+i*a,a+b);
	}
	else if(i == 0)//第一个子进程		
	{
		memcpy(q,p,a);
	}
	else
	{
		memcpy(q+i*a,p+i*a,a);
	}

	//释放映射区
	int ret = munmap(p,size);
	if(ret == -1)
	{
		perror("p munmap error");
		exit(1);
	}
	
	int res = munmap(q,size);
	if(res == -1)
	{
		perror("q munmap error");
		exit(1);
	}

	return 0;
}

**

运行结果:

**
在这里插入图片描述

这篇关于Ubuntu下基于mmap映射区的多进程拷贝(运行成功)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!