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
      
    

      

  • 相关阅读:
    < java.util >-- Set接口
    Codeforces 627 A. XOR Equation (数学)
    Codeforces 161 B. Discounts (贪心)
    Codeforces 161 D. Distance in Tree (树dp)
    HDU 5534 Partial Tree (完全背包变形)
    HDU 5927 Auxiliary Set (dfs)
    Codeforces 27E. Number With The Given Amount Of Divisors (暴力)
    lght oj 1257
    Codeforces 219D. Choosing Capital for Treeland (树dp)
    Codeforces 479E. Riding in a Lift (dp + 前缀和优化)
  • 原文地址:https://www.cnblogs.com/mathzzz/p/2688544.html
Copyright © 2011-2022 走看看