使用多线程分片断拷贝一个普通文件

来源:互联网 发布:淘宝规定多长时间发货 编辑:程序博客网 时间:2024/05/27 14:14

程序的执行方式为:

./a.out n src dst (其中n代表线程数量)
/************************************************************************* * File Name: copyfile.c * Author: lixiaogang * Function: 线程拷贝文件 * Mail: 2412799512@qq.com  * Created Time: 2017年06月12日 星期一 21时32分08秒 ************************************************************************/#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<pthread.h>#include<string.h>#include<unistd.h>typedef struct {    char src_file[1024];    char dst_file[1024];    int start;    int length;}Args;/* 封装出错打印函数 */void sys_err(const char *ptr,int num){    perror(ptr);    exit(num);}void *pthreadFunc(void *args){    Args *arg = (Args *)args;    int src_fd = open(arg->src_file,O_RDONLY);    int dst_fd = open(arg->dst_file,O_WRONLY);    lseek(src_fd,arg->start,SEEK_SET);    lseek(dst_fd,arg->start,SEEK_SET);    char buf[1024];    while(arg->length > 0)    {        memset(buf,0x00,sizeof(buf));        int len = read(src_fd,buf,arg->length);        if(len < 0)        {            break;        }        /* 向文件写入真实读到的字节数 */        write(dst_fd,buf,len);        arg->length -= len;    }    free(arg);    close(src_fd);    close(dst_fd);}/* 文件拷贝实现 */void copyFile(int num,const char *src,const char *dst){    struct stat st;    int i;    int flag = stat(src,&st);    if(flag < 0)    {        sys_err("stat",-1);    }    /* num个线程,平均每个线程负责拷贝的数据块大小*/    int averageSize = st.st_size / num;    /* num线程个数不确定,所以把余下的数据块给最后线程*/    int lastSize = st.st_size % num;     int dstfd = open(dst,O_CREAT,0777);    if(dstfd < 0)    {        sys_err("open",-2);    }    /*为目标文件分配源文件大小的内存空间*/    ftruncate(dstfd,st.st_size);    close(dstfd);    pthread_t *tid = (pthread_t *)malloc(sizeof(pthread_t) * num);    if(NULL == tid)    {        sys_err("pthread_t malloc",-3);    }    for(i = 0;i < num; ++i)    {        Args *arg = (Args *)malloc(sizeof(Args));        strcpy(arg->src_file,src);        strcpy(arg->dst_file,dst);        arg->start = averageSize * i;        /* 判断是否为最后的一个线程,若是,则其拷贝数据块+lastsSize */        if(i == num - 1)            arg->length = averageSize + lastSize;        else            arg->length = averageSize;        /* 创建线程 */        pthread_create(tid + i,NULL,pthreadFunc,(void *)arg);        /* 回收线程所占用的内存资源 */    }    for(i = 0; i< num; ++i)    {        pthread_join(tid[i],NULL);    }    free(tid);}int main(int argc,char *argv[]){    /* ./a.out n src dst */    if(argc != 4)    {        printf("Usage: filename num src dst.\n");        return -1;    }    const char *src = argv[2];    const char *dst = argv[3];    int num = atoi(argv[1]);    /*拷贝文件*/    copyFile(num,src,dst);    return 0;}