多进程可以加快大文拷贝的速率,利用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映射区的权限相同或者大于,要不然会出现段错误。