zoukankan      html  css  js  c++  java
  • 多线程copy文件,另加进度条显示 分类: C语言学习 2015-06-12 16:24 87人阅读 评论(0) 收藏

    /*Ubuntu 14.04平台下
    * 利用多线程 mmap文件内存共享
    * 实现文件拷贝
    */
    
    /*more thread copy files
    *  默认情况下开启5个线程
    */
    #include <stdio.h>
    #include <sys/stat.h>
    #include <sys/mman.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <string.h>
    #include <pthread.h>
    #include <errno.h>
    #include <sys/types.h>
    
    /*thread number*/
    #define T_NUM 5
    #define ITEMS 50
    
    typedef struct{
        /*off size,file size,thread identifier */
        int off,size,t_no;
    }arg_t;
    
    void err_sys(void *str)
    {
        perror(str);
        exit(1);
    }
    
    void err_usr(char *str)
    {
        fputs(str,stderr);
        exit(1);
    }
    
    char *pch_sour_file,*pch_des_file;
    int *pi_has_done;
    int pnum=T_NUM;
    
    /*arg {off,size,t_no}*/
    void *pt_cp(void *arg)
    {
        if(NULL==arg)
            return NULL;
        arg_t *arg_p;int i;
        char *pch,*qch;
        arg_p=(arg_t *)arg;
        pch=pch_sour_file+arg_p->off,qch=pch_des_file+arg_p->off;
        for(i=0;i<arg_p->size;i++)
        {
            *qch++=*pch++;
            pi_has_done[arg_p->t_no]++;
            /*usleep function is like to sleep*/
            usleep(5000);
        }
        return NULL;
    }
    void *display_pro(void * arg)
    {
        int size,draw=0,sum,i,j,interval;
        size=(int)arg;
        interval=size/ITEMS;
        while(draw<ITEMS)
        {
            for(i=0,sum=0;i<pnum;i++)
                sum+=pi_has_done[i];
            j=sum/interval+1;
            for(;j>draw;draw++)    
                putchar('=');fflush(stdout);
        }
        printf("
    ");
        return NULL;
    }
    int main(int argc,char *argv[])
    {
        int src,dst,i,len,off;
        struct stat statbuff;
        pthread_t *tid;
        arg_t *arg_arr;
        if(argc!=3 && argc!=4)    
            err_usr("usage:cp src dst [pthread_no]
    ");
        /*修改线程数*/
        if(argc==4)
            pnum=atoi(argv[3]);
        src=open(argv[1],O_RDONLY);
        if(src<0)
        {printf("fail to open %s
    ",argv[1]);return -1;}
    
        dst=open(argv[2],O_RDWR | O_CREAT | O_TRUNC,0644);
        if(dst<-1)
        {printf("fail to open %s
    ",argv[2]);return -1;}
    
        if(fstat(src,&statbuff)==-1)
        {
            err_sys("fail to stat");
            return -1;
        }
    
        /*创建同样的大小文件*/
        lseek(dst,statbuff.st_size-1,SEEK_SET);
        write(dst,"a",1);
    
    
        pch_sour_file=(char *)mmap(NULL,statbuff.st_size,PROT_READ,MAP_SHARED,src,0);
        if(pch_sour_file==MAP_FAILED)
        {
            err_sys("fail to mmap");
            return -1;
        }
    
        pch_des_file=(char *)mmap(NULL,statbuff.st_size,PROT_WRITE,MAP_SHARED,dst,0);
        if(pch_des_file==MAP_FAILED)
        {
            err_sys("fail to mmap");
            return -1;
        }
    
        /*close file discription*/    
        close(src);close(dst);
        /*crate pthread tid[n+1]*/
        tid=(pthread_t *)malloc(sizeof(pthread_t)*(pnum+1));
        if(NULL==tid)
        {
            err_sys("fail to malloc");
            return -1;
        }
    
        /*per thread copy bite*/
        /*每个线程需要的拷贝的字节数*/
        pi_has_done=(int *)calloc(sizeof(int),pnum);
        if(NULL==pi_has_done)
        {
            err_sys("fail to calloc");
            return -1;
        }    
        /*arg_arr[n] per thread task*/
        arg_arr=(arg_t *)malloc(sizeof(arg_t)*pnum);
        if(NULL==arg_arr)
        {
            err_sys("fail to malloc");    
            return -1;
        }
        /*allocating task*/
        len=statbuff.st_size/pnum,off=0;
        for(i=0;i<pnum;i++,off+=len)
            arg_arr[i].off=off,arg_arr[i].size=len,arg_arr[i].t_no=i;
        /*reminder byte add last struct arg_t*/
        arg_arr[pnum-1].size+=statbuff.st_size%pnum;
        /*create pthread to do*/        
        for(i=0;i<pnum;i++)
            pthread_create((tid+i),NULL,pt_cp,(void *)(arg_arr+i));
        /*专门显示进度的线程*/
        pthread_create((tid+pnum),NULL,display_pro,(void *)statbuff.st_size);
        for(i=0;i<pnum;i++)
            pthread_join(tid[i],NULL);
        /*关闭文件共享*/
        munmap(pch_sour_file,statbuff.st_size);
        munmap(pch_des_file,statbuff.st_size);
        /*回收内存*/
        free(tid);
        free(arg_arr);
        free(pi_has_done);
        return 0;
    }
    
    
    
    效果图如下所示:

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    《学习之道》第二章学习方法7看视频
    《学习之道》第二章学习6阅读书籍
    反射详解一
    spring 初始化和销毁的三种方法
    文件读取
    JdbcTemplate 详解二
    JdbcTemplate 详解一
    JdbcTemplate 详解三
    常用commons 工具类依赖配置
    java 8 stream
  • 原文地址:https://www.cnblogs.com/L-Lune/p/4671282.html
Copyright © 2011-2022 走看看