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; }

備考:汪さんの設計構想を参考にする