多线程
来源:互联网 发布:ubuntu 16.04输入法 编辑:程序博客网 时间:2024/06/05 08:47
多线程拷贝命令的实现,如:./my_cp src_file dest_file N(拷贝线程个数)
思路:先把src_file用mmap映射到内存里面,私人模式,然后创建dest_file,文件大小于src一样,也映射到内存空间去,然后把根据线程个数,把文件分割.
定义一个结构体,元素有每个线程要拷贝的起始指针位置,块大小,以及这是第几个线程.
定义一个全局整形数组指针,指向一个动态数组空间,数组的大小和线程的个数一致,用于进度条.
代码的实现:
#include <stdio.h>#include <string.h>#include <sys/mman.h>#include <unistd.h>#include <stdlib.h>#include <sys/stat.h>#include <pthread.h>#include <sys/types.h>#include <fcntl.h>int *array;void sys_err(const char *str){ perror(str); exit(0);}struct cp { char *srcm_add; char *destm_add; int thread_num; int block_size;};void *thread_cpy(void *arg){ struct cp *im = (struct cp *)arg; int block = im->block_size; char *srcm_add = im->srcm_add; char *destm_add = im->destm_add; while(block--) { //One byte of a byte copy *destm_add++ = *srcm_add++; array[im->thread_num]++; usleep(1000); } free(im);}int main(int argc, char *argv[]){ int fdsrc, fddest; int src_size = 0; char *srcm_add, *destm_add; int block_size; int thread_num; pthread_t tid; struct cp *im; int i; int err; int sum = 0; pthread_attr_t attr; struct stat st; if (argc < 3) { printf("./a.out srcfile destfile\n"); exit(1); } /* open fdsrc ,get fdsrc size*/ if((fdsrc = open(argv[1], O_RDONLY)) < 0) sys_err("open src"); if((src_size = lseek(fdsrc, 0, SEEK_END)) < 0) sys_err("lseek fdsrc"); if(stat(argv[1], &st)) sys_err("stat"); st.st_mode &= 0777; /* create fddest, mode and size*/ if((fddest = open(argv[2], O_CREAT|O_RDWR, st.st_mode)) < 0) sys_err("open dest"); if(lseek(fddest, src_size-1, SEEK_SET) < 0) sys_err("lseek dest"); if(write(fddest, "\0", 1) < 0) sys_err("write creat dest"); /* block number*/ if(argc == 3) thread_num = 5; else thread_num = atoi(argv[3]); /* chick num */ array = calloc(sizeof(int), thread_num); /* copy file to mmap */ srcm_add = mmap(NULL, src_size, PROT_READ, MAP_PRIVATE, fdsrc, 0); destm_add = mmap(NULL,src_size, PROT_WRITE, MAP_SHARED, fddest, 0); pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); /* create thread */ for (i=0; i<thread_num; i++) { if(i == (thread_num-1)) block_size = src_size/thread_num + src_size%thread_num; else block_size = src_size/thread_num; im = calloc(sizeof(struct cp), 1); im->srcm_add = srcm_add + i * (src_size/thread_num); im->destm_add = destm_add + i * (src_size/thread_num); im->block_size = block_size; im->thread_num = i; err = pthread_create(&tid, &attr, thread_cpy, (void *)im); if(err != 0) fprintf(stderr, "%s\n", strerror(err)); } int j, k = 1; j = src_size/20; do { sum = 0; for (i=0; i<thread_num; i++) sum += array[i]; if(sum > j*k) { k++; write(STDOUT_FILENO, "==", 2); } usleep(10000); } while(sum < src_size); printf("\n"); free(array); munmap(srcm_add, src_size); munmap(destm_add, src_size); return 0;}
注意:如果要映射的文件过大,不能一下子全部映射内存里面,要一部分一部分的映射到内存里面,然后在一点一点往另一个内存拷贝,但还要注意,mmap的最小偏移量4096。
#include <stdio.h>#include <string.h>#include <sys/mman.h>#include <unistd.h>#include <stdlib.h>#include <sys/stat.h>#include <pthread.h>#include <sys/types.h>#include <fcntl.h>int *array;void sys_err(const char *str){ perror(str); exit(0);}struct cp { char *srcm_add; char *destm_add; int thread_num; int block_size;};void *thread_cpy(void *arg){ struct cp *im = (struct cp *)arg; int block = im->block_size; char *srcm_add = im->srcm_add; char *destm_add = im->destm_add; while(block--) { //One byte of a byte copy *destm_add++ = *srcm_add++; array[im->thread_num]++; usleep(100); } free(im);}int main(int argc, char *argv[]){ int fdsrc, fddest; int src_size = 0; char *srcm_add, *destm_add; int block_size; int thread_num; pthread_t tid; struct cp *im; int i; int err; int sum = 0; pthread_attr_t attr; struct stat st; int page_size; int page_num; int page_count = 0; if (argc < 3) { printf("./a.out srcfile destfile\n"); exit(1); } /* open fdsrc ,get fdsrc size*/ if((fdsrc = open(argv[1], O_RDONLY)) < 0) sys_err("open src"); if((src_size = lseek(fdsrc, 0, SEEK_END)) < 0) sys_err("lseek fdsrc"); if(stat(argv[1], &st)) sys_err("stat"); st.st_mode &= 0777; /* create fddest, and set size*/ if((fddest = open(argv[2], O_CREAT|O_RDWR, st.st_mode)) < 0) sys_err("open dest"); if(lseek(fddest, src_size-1, SEEK_SET) < 0) sys_err("lseek dest"); if(write(fddest, "\0", 1) < 0) sys_err("write creat dest"); if(argc == 3) thread_num = 5; else thread_num = atoi(argv[3]); pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if(src_size > 4096) { page_num = src_size/4096 + 1; for(page_count=0; page_count<page_num; page_count++) { array = calloc(sizeof(int), thread_num); if(page_count == (page_num-1)) page_size = src_size%4096; else page_size = 4096; srcm_add = mmap(NULL, page_size, PROT_READ, MAP_PRIVATE, fdsrc, 4096*page_count); destm_add = mmap(NULL,page_size, PROT_WRITE, MAP_SHARED, fddest, 4096*page_count); for (i=0; i<thread_num; i++) { if(i == (thread_num-1)) block_size = page_size/thread_num + page_size%thread_num; else block_size = page_size/thread_num; im = calloc(sizeof(struct cp), 1); im->srcm_add = srcm_add + i * (page_size/thread_num); im->destm_add = destm_add + i * (page_size/thread_num); im->block_size = block_size; im->thread_num = i; err = pthread_create(&tid, &attr, thread_cpy, (void *)im); if(err != 0) fprintf(stderr, "%s\n", strerror(err)); } int j, k = 1; j = page_size/20; do { sum = 0; for (i=0; i<thread_num; i++) sum += array[i]; if(sum > j*k) { k++; write(STDOUT_FILENO, "==", 2); } usleep(10000); } while(sum < page_size); printf("\n"); free(array); munmap(srcm_add, page_size); munmap(destm_add, page_size); } } return 0;}
0 0
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 利用QT自带的windeployqt打包发布程序
- windows安装程序无法将windows配置为此计算机的硬件上运行
- C++之枚举类型探索
- bzoj3156(斜率优化DP)
- 冒泡排序&第一次在CSDN上写博客
- 多线程
- 递归方法实现逆序
- activity生命周期--onFreeze详解
- linux下自己安装软件添加快捷方式
- POJ2031(最小生成树)
- 使用 python脚本获取函数调用关系
- Qt 注册表
- Python3 实现网站后台弱口令爆破(多线程)
- android shape的使用