多线程
2015-12-01 21:14
429 查看
多线程拷贝命令的实现,如:./my_cp src_file dest_file N(拷贝线程个数)
思路:先把src_file用mmap映射到内存里面,私人模式,然后创建dest_file,文件大小于src一样,也映射到内存空间去,然后把根据线程个数,把文件分割.
定义一个结构体,元素有每个线程要拷贝的起始指针位置,块大小,以及这是第几个线程.
定义一个全局整形数组指针,指向一个动态数组空间,数组的大小和线程的个数一致,用于进度条.
代码的实现:
注意:如果要映射的文件过大,不能一下子全部映射内存里面,要一部分一部分的映射到内存里面,然后在一点一点往另一个内存拷贝,但还要注意,mmap的最小偏移量4096。
思路:先把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 b97b *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; }
相关文章推荐
- Linux socket 初步
- Python3写爬虫(四)多线程实现数据爬取
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- 关于指针的一些事情
- Scientific Linux 5.5 图形安装教程
- 基于 Linux 集群环境上 GPFS 的问题诊断