多进程和多线程文件拷贝

多进程和多线程文件拷贝

多进程拷贝

思路:根据进程数对要拷贝的文件进行分段拷贝,主进程拷贝多余出来的字节

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值