Linuxマルチスレッドファイルコピー
14653 ワード
友人の設計思想を参考に,コード実装ファイルのマルチスレッドレプリケーションを再作成した.
fcp.h :
#ifndef __FCP_H
#define __FCP_H
#define MAX 125
//define read block struct
typedef struct _page
{
char fin[MAX];
char fout[MAX];
long offset;
long size;
int id;
}__attribute__((packed)) page;
int multi_copy();
#endif
fcp.c :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include "fcp.h"
#define THREAD_SIZE 5
#define UNIT 16*1024
//get file size
int fsize(char *filename)
{
struct stat st;
memset(&st,0,sizeof(st));
stat(filename,&st);
return st.st_size;
}
int thread_copy(void *arg)
{
page *p1=(page *)arg;
char buf[UNIT];
memset(buf,0,sizeof(buf));
FILE *in=fopen(p1->fin,"r");
FILE *out=fopen(p1->fout,"rb+");
if(out==NULL||NULL==in)
{
fprintf(stderr,"source/target file is null
");
return -1;
}
printf("Thread id=%ld,id=%d
",pthread_self(),p1->id);
printf("\tp1->id=%d,p1->offset=%ld,p1->size=%ld
",p1->id,p1->offset,p1->size);
fseek(in,p1->offset,SEEK_SET);
fseek(out,p1->offset,SEEK_SET);
long size=p1->size;
int len,writen,left;
while(size>0)
{
len=size;
if(len>sizeof(buf))
{
len=sizeof(buf);
}
len=fread(buf,1,len,in);
if(len<0){fprintf(stderr,"read src file error
");break;}
size-=len;
writen=0;
left=len;
while(left>0)
{
len=fwrite(buf,1,left,out);
if(len<0){fprintf(stderr," write target file error
");break;}
writen+=len;
left-=len;
}
}
fclose(in);
fclose(out);
printf("********Thread %ld ,id = %d,exit
",pthread_self(),p1->id,writen);
pthread_exit(NULL);
return 0;
}
int multi_copy(char *src,char *dest)
{
if(0!=access(src,F_OK)){fprintf(stderr,"file is not exists
");return -1;}
if(0==access(dest,F_OK)){remove(dest);}
size_t size=fsize(src);
int fd=open(dest,O_RDWR|O_CREAT,0666);
if(fd<0)
{
close(dest);
fprintf(stderr," file open error
");
return -1;
}
if(fallocate(fd,0,0,size)!=0)
{
close(fd);
fprintf(stderr,"create file error
");
return -1;
}
close(fd);
int thread_size=THREAD_SIZE;
int i;
if(size<thread_size){thread_size=1;}
pthread_t works[thread_size];
page *p=(page *)malloc(sizeof(*p)*thread_size);
if(!p){fprintf(stderr," malloc memory for page error
");return -1;}
long per_size=size/thread_size;
printf(" Thread size =%d,Percent size =%d
",thread_size,per_size);
long offset=0;
for(i=0;i<thread_size;i++)
{
strncpy(p[i].fin,src,strlen(src));
strncpy(p[i].fout,dest,strlen(dest));
p[i].offset=offset;
p[i].id=i;
if(i==(thread_size-1))
{
p[i].size=size-offset;
}
else
{
p[i].size=per_size;
}
offset+=per_size;
}
for(i=0;i<thread_size;i++)
{
pthread_create(&works[i],NULL,(void *)&thread_copy,(void *)&p[i]);
}
for(i=0;i<thread_size;i++)
{
pthread_join(works[i],NULL);
}
if(p!=NULL)
{
free(p);
p=NULL;
}
return 0;
}
void usage()
{
printf("usage: fcp sourcefile targetfile
");
}
int main(int argc,char *args[])
{
if(argc<3)
{
usage();
return -1;
}
char *fin=args[1];
char *fout=args[2];
printf("
*******%s size =%ld
",fin,fsize(fin));
multi_copy(fin,fout);
return 0;
}
備考:汪さんの設計構想を参考にする