zoukankan      html  css  js  c++  java
  • 带进度条的多线程拷贝

    ---------- SUB_FUN.C
    #include "mul_cp.h"
    extern char *src_addr, *dest_addr;
    static char *sub_bar(int gain, int all, char *buf, int len, int num)
    {
        int block = len/num;
        if(len % num != 0)
            block += 1;
    
        int i;
        for(i = 0; i<block; i++)
            if(i <= block * gain /all)
                buf[i] = '>';
            else
                buf[i] = ' ';
        buf[i] = 0;
        return buf;
    }
    
    void disp_bar(cp_task *task, int num)
    {
    	int i, i_gain;
    	int cur = 0, all = 0;
    	char bar[60];
        char *sch;
    
    	for(i = 0; i<num; i++)
    		all += task[i].off;
    
    	while(cur < all){
    		usleep(1000);
    		cur = 0;
    		for(i = 0; i<num; i++) {
    			i_gain = task[i].cur_gain;
    			cur += i_gain;
                sch = sub_bar(i_gain, task[0].off, bar, sizeof(bar), num);
    			printf("%s", sch);
    		}
    		printf("]%4.1f%%\r[", cur*100.0/all);
    	}
    	puts("");
    }
    
    
    int assign_task(int src_filesize, int num, cp_task *task_sch)
    {
        int block_size;
    	block_size = src_filesize / num;
    	if(src_filesize % num != 0) // 如果不能整除,块大小= 总数/份数 + 1
    		block_size += 1; 
    
        int i;
        for(i = 0; i < num; i++){
    		task_sch[i].id = i;
            task_sch[i].base = i * block_size; 
            task_sch[i].off = block_size;
        }
    	task_sch[num-1].off = src_filesize - block_size * (num - 1);
    }
    
    int parse_arg(const int argc, const char **argv, const char **src, const char **dest, int *pthread_num)
    {
    	if(argc != 4)
    	{
    		printf("%s %s %s %s\n",argv[0],  "<thread_number>", "<src file>", "<dest file>");
    		exit(0);
    	}
    
    	*pthread_num = atoi(argv[1]);
        *src = argv[2];
        *dest = argv[3];
    
        return *pthread_num;
    }
    
    int create_map(int src_filesize, const char *src_file, const char *dest_file, char **src_addr, char **dest_addr)
    {
        int src_fd, dest_fd;
        if((src_fd = open(src_file, O_RDONLY)) < 0){
            perror("open src_fd");
            exit(1);
        }
    
        if((dest_fd = open(dest_file, O_RDWR|O_CREAT|O_TRUNC, 0644)) < 0){
            perror("open dest_fd");
            exit(2);
        }
    	lseek(dest_fd, src_filesize-1, SEEK_SET); // 目标文件大小必须和源文件大小相等方可对等映射
    	write(dest_fd, "", 1);
    
    	*src_addr = mmap(NULL, src_filesize, PROT_READ, MAP_SHARED, src_fd, 0);
    	if(*src_addr == MAP_FAILED){
    		perror("mmap");
    		exit(3);
    	}
    
        *dest_addr = mmap(*src_addr + src_filesize, src_filesize, PROT_WRITE, MAP_SHARED, dest_fd, 0);
    	if(*dest_addr == MAP_FAILED){
    		perror("mmap");
    		exit(4);
    	}
    
        close(src_fd);
        close(dest_fd);
    }
    
    int get_filesize(const char *name) 
    {
    	int fd = open(name, O_APPEND);
    	if(fd < 0)
    	{
    		perror("get_filesize-->open:");
    		exit(-1);
    	}
    	off_t off = lseek(fd, 0, SEEK_END);	
    	close(fd);
    	return off;
    }
    
    ---------- MUL_CP.H
    #ifndef MUL_CP
    #define MUL_CP
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <assert.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <string.h>
    #include <time.h>
    #include <sys/mman.h>
    #include <pthread.h>
    
    #define gotoxy(line, cols)	fprintf(stderr, "\033[%d;%dH", (line),(cols))
    #define my_hide_curse() 	fprintf(stderr, "\033[?25l")
    #define my_show_curse() 	fprintf(stderr, "\033[?25h")
    
    typedef struct {
    		int id;
            int base;
            int off;
            int cur_gain;
    }cp_task;
    
    void disp_bar(cp_task *task, int num);
    static char *sub_bar(int gain, int all, char *buf, int len, int num);
    int assign_task(int src_filesize, int num, cp_task *task_sch);
    int parse_arg(const int argc, const char **argv, const char **src, const char **dest, int *pthread_num);
    int create_map(int src_filesize, const char *src_file, const char *dest_file, char **src_addr, char **dest_addr);
    
    #endif
    
    ---------- MUL_CP.C
    #include "mul_cp.h"
    
    char *src_addr, *dest_addr; // 映射的文件内存地址;
    
    static void copy(char *src_addr, char *dest_addr, cp_task *task)
    {
    	char *src = src_addr + task->base;
    	char *dest = dest_addr + task->base;
    	int i;	
    	for(i = 0; i < task->off; i++){
    		 task->cur_gain = i+1;
    		 dest[i] = src[i];
             usleep(100);
    	}
    }
    
    void *mul_cp(void *arg)
    {
    	cp_task *p = arg;
    	copy(src_addr, dest_addr, p);
    }
    
    void show_curse(int arg)
    {
        my_show_curse();
        puts("");
        exit(0); // 主线程退出, 如果没有,则其他线程继续运行
    }
    
    int main(const int argc, const char *argv[])
    {
        // 0. 初始化
        signal(SIGINT, show_curse);
        my_hide_curse();
    
        // 1. 命令行解析
        const char *src_file;
        const char *dest_file;
        int pthread_num;
    	setbuf(stdout, NULL);
        parse_arg(argc, argv, &src_file, &dest_file, &pthread_num);
    
        // 2. 获取src文件属性,如文件大小
        int src_filesize;
        src_filesize = get_filesize(src_file);
    	
    	// 3. 创建映射文件
        create_map(src_filesize, src_file, dest_file, &src_addr, &dest_addr);
    
        // 4. 分派任务
        cp_task task_sch[pthread_num];
        memset(&task_sch, 0, sizeof(task_sch));
    	assign_task(src_filesize, pthread_num, task_sch);
    
        // 5. 创建多线程
    	int i;
    	pthread_t tid[pthread_num];
        for(i = 0; i<pthread_num; i++)
            pthread_create(tid+i, NULL, mul_cp, task_sch+i);
    	
    	// 6. 显示下载进度
        disp_bar(task_sch, pthread_num);
    
    	// 7. 线程回收等待
    	for(i = 0; i<pthread_num; i++)
    		pthread_join(tid[i], NULL);
    
        // 8. 恢复光标显示
        my_show_curse();
    
        return 0;
    }
    
    ---------- MAKEFILE
    all:
    	gcc mul_cp.c sub_cp.c -o xcp
    clean:
    	-rm xcp *.~ a.out
    
    ---------- MUL.TXT
      
    

      

  • 相关阅读:
    【ybt金牌导航4-7-3】【luogu P3437】三维俄罗斯方块 / TET-Tetris 3D
    【ybt金牌导航4-6-6】【luogu P2617】【ybt金牌导航4-7-4】动态排名 / Dynamic Rankings
    【ybt金牌导航4-6-4】【luogu P3402】可持久化并查集
    【luogu P5055】【模板】可持久化文艺平衡树
    【ybt金牌导航4-6-2】【luogu P3835】可持久化平衡树
    【luogu P4278】【ybt金牌导航4-5-2】带插入区间K小值(树套树做法)
    【luogu P3369】普通平衡树(fhq Treap 做法)
    【ybt金牌导航4-4-2】【luogu P2042】维护数列(fhq Treap 做法)
    【luogu P3369】普通平衡树(Treap 做法)
    匿名函数
  • 原文地址:https://www.cnblogs.com/mathzzz/p/2688544.html
Copyright © 2011-2022 走看看