多进程和多线程文件拷贝
多进程拷贝
思路:根据进程数对要拷贝的文件进行分段拷贝,主进程拷贝多余出来的字节
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/wait.h>
//得到源文件的大小
int getfilesize(const char* filename){
struct stat buf;
stat(filename,&buf);
return buf.st_size;
}
//进程分段拷贝
void copy_frag(int srcfd,int dstfd,int start,int len){
lseek(srcfd,start,SEEK_SET);
lseek(dstfd,start,SEEK_SET);
char buf[4096];
while(len>0){
int copylen=len<sizeof(buf)?len:sizeof(buf);
int ret=read(srcfd,buf,copylen);
if(ret<0) break;
write(dstfd,buf,ret);
len-=ret;
}
}
//拷贝文件函数
void copyfile(int jobs,const char* srcfile,const char* dstfile){
int filesize=getfilesize(srcfile);
int srcfd=open(srcfile,O_RDONLY);
int dstfd=open(dstfile,O_WRONLY|O_CREAT,0777);
//14/4=2;
int frag=filesize/jobs;//记录每个线程需要复制的文件块大小
int i;
//创建多个子进程,进行分段拷贝
for(i=0;i<jobs;i++){
pid_t pid=fork();
if(pid==0){
copy_frag(srcfd,dstfd,frag*i,frag);
return;
}
}
//主进程拷贝剩余的部分
copy_frag(srcfd,dstfd,frag*i,filesize-frag*jobs);
//等待子进程拷贝结束,进行回收
for(i=0;i<jobs;i++){
wait(NULL);
}
close(srcfd);
close(dstfd);
}
//./a.out -j 4 srcfile dstfile
int main(int argc,char *argv[]){
if(argc!=5){
printf("argument error");
return -1;
}
if(strcmp(argv[1],"-j")!=0){
printf("argv -j error");
return -1;
}
int jobs=atoi(argv[2]);
const char* srcfile=argv[3];
const char* dstfile=argv[4];
copyfile(jobs,srcfile,dstfile);
return 0;
}
多线程拷贝
思路:类似多进程,也是根据线程数分段拷贝
#include<stdio.h>
#include<fcntl.h>
#include<pthread.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
//存储文件拷贝信息
struct fileinfo{
char* srcname;
char* dstname;
size_t start;//每个线程文件拷贝的起始位置
size_t end;//每个线程文件的结束位置
}info[10];
//线程拷贝
void *copyfunc(void *arg){
struct fileinfo* tempinfo=(struct fileinfo*)arg;
printf("%d===pthread begining to copy==========\n",(int)pthread_self());
int srcfd=open(tempinfo->srcname,O_RDONLY);
int dstfd=open(tempinfo->dstname,O_WRONLY|O_CREAT,0777);
if(srcfd<0||dstfd<0){
perror("open");
pthread_exit(NULL);
}
lseek(srcfd,tempinfo->start,SEEK_SET);
lseek(dstfd,tempinfo->start,SEEK_SET);
int insize=tempinfo->end-tempinfo->start;//线程需要拷贝文件块大小
printf("start:%d end:%d insize:%d\n",tempinfo->start,tempinfo->end,insize);
char buf[1024];
while(insize>0){
int readsize=insize<sizeof(buf)?insize:sizeof(buf);
int ret=read(srcfd,buf,readsize);
write(dstfd,buf,ret);
insize-=readsize;
}
printf("%d===pthread end to copy==========\n",(int)pthread_self());
}
//./a.out 3 srcfile dstfile
int main(int argc,char* argv[]){
if(argc!=4){
printf("usage:./a.out 4 srcfile dstfile\n");
return -1;
}
int i;
int pthreadnum=atoi(argv[1]);
pthread_t tid[10];
struct stat stat_buf;
stat(argv[2],&stat_buf);
int filesize=stat_buf.st_size;
int fragsize=filesize/pthreadnum;//线程需要拷贝文件块大小
for(i=0;i<pthreadnum;i++){
info[i].srcname=argv[2];
info[i].dstname=argv[3];
info[i].start=i*fragsize;
info[i].end=info[i].start+fragsize;
}
info[i-1].end=filesize;//最后一个线程拷贝的结束位置
for(i=0;i<pthreadnum;i++){
pthread_create(&tid[i],NULL,copyfunc,&info[i]);
}
for(i=0;i<pthreadnum;i++){
pthread_join(tid[i],NULL);
}
return 0;
}