Linux 多线程文件复制

 

参考了朋友的设计思想,重新编写了代码实现文件的多线程复制

 

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\n");
        return -1;
    }
    printf("Thread id=%ld,id=%d\n",pthread_self(),p1->id);
    printf("\tp1->id=%d,p1->offset=%ld,p1->size=%ld\n",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\n");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\n");break;}
            writen+=len;
            left-=len;
        }
    }
    fclose(in);
    fclose(out);
    printf("********Thread %ld ,id = %d,exit\n",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\n");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\n");
        return -1;
    }
    if(fallocate(fd,0,0,size)!=0)
    {
        close(fd);
        fprintf(stderr,"create file error\n");
        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\n");return -1;}
    long per_size=size/thread_size;
    printf("  Thread size =%d,Percent size =%d\n",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\n");
}
int main(int argc,char *args[])
{
    if(argc<3)
    {
        usage();
        return -1;
    }
    char *fin=args[1];
    char *fout=args[2];
    printf("\n*******%s  size =%ld\n",fin,fsize(fin));
    multi_copy(fin,fout);
    return 0;
}

备注:参考老汪的设计思路

你可能感兴趣的:(Linux 多线程文件复制)