linux ------- 多进程实现大文件拷贝

多进程可以加快大文拷贝的速率,利用fork,创建子进程进行多个进程同时处理拷贝任务。

/*************************************************************************
	> File Name: project.c
	> Author: xuchen_allen
	> Mail: [email protected] 
	> Created Time: 2019年02月03日 星期日 10时35分47秒
 ************************************************************************/

#include<stdio.h>
#include<sys/types.h>
#include<sys/mman.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<sys/wait.h>
#include<string.h>
int main(int argc,char*argv[])
{
	struct stat infor;
	int fd,fd_copy;

	//创建一个接受拷问数据的文件:
	fd_copy=open("copy_test",O_RDWR|O_CREAT|O_TRUNC,0644);
    if(fd_copy<0){
		perror("open copy fail");
		exit(1);
	}
	if(argc<2){
		perror("worng");
		exit(1);
	}

	fd = open(argv[1],O_RDONLY);
	if(fd<0){
		perror("open fail");
		exit(1);
	}
	fstat(fd,&infor);

	int len = infor.st_size;
	printf("len=%d\n",len);

	
	//获得了需要拷贝的文件的大小:

	//设置接受拷贝的文件大小:
	if(lseek(fd_copy,len-1,SEEK_SET)==-1){
		perror("lseek fail");
		exit(1);
	}
	if(write(fd_copy,"",1)!=1){
		perror("write fail");
		exit(1);
	}

	char *buf = (char*)mmap(0,len,PROT_READ|PROT_WRITE,MAP_SHARED,fd_copy,0);
	char *dst = buf;
	close(fd_copy);
	//创建接受拷贝的文件的映射区:
	

	//创建映射区;
	char *area;
	pid_t pid;

	area = (char *)(mmap(0,len,PROT_READ,MAP_SHARED,fd,0));
	//area标志映射区的起始地址;
	if(area==MAP_FAILED){
		perror("mmap failed");
		exit(1);
	}
	char *temp = area;
	close(fd);
	//创建好了映射区,将需要拷贝的文件放进映射区;
	
	
	//此时计算需要几个子进程:
	int n,j,i;
	if((j=len%100)){
		n=len/100+1;
		//n为需要的子进程数,j为最后一个子进程处理的字节数;
	}
	else if(len<=100)
		n=1;//文件长度小于或等于100时;
	else
		n=len/100;//正好整除时;
	printf("文件大小为:%d\t,需要:%d\t 个子进程帮助。\n",len,n);

	//创建子进程:
	for(i=0;i<n;i++){
		pid = fork();
		if(pid == -1){
			perror("fork fail");
			exit(1);
		}
		else if(pid == 0){//进入子进程
			break;//跳出循环,真正进入子进程内部;
		}
	}
	if(i<n){//正真进入子进程;
	//	printf("*dst=%s\n",*dst);
		sleep(i);
		printf("我是第%d个子进程,我拷贝了%d个字节。\n",i+1,(i<n-1)?100:j);//观察子进程实时运行状态;
		//开始拷贝文件:
		if(i<n-1){
			printf("++++++++++\n");
			dst+=i*100;
			temp+=i*100;
			memcpy(dst,temp,100);
		}
		else{
			dst+=i*100;
			temp+=i*100;
			memcpy(dst,temp,j);
		}
	}
	else{//进入父进程;
			sleep(n);
			wait(NULL);
			printf("parent rlease.\n");
	}
        munmap(area,len);
        munmap(buf,len);

	exit(0);
}

注意:

文件打开的权限一定要与mmap映射区的权限相同或者大于,要不然会出现段错误。

发布了158 篇原创文章 · 获赞 37 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/XUCHEN1230/article/details/86758326