实现多线程拷贝命令,如:./multithread_copy srcfile destfile N(拷贝线程个数)
难点:
内存映射mmap。
给每一个线程合理的分配任务。
多线程的实现。
具体的实现代码如下:
/************************************************************************* > File Name: multithread_copy.c > Author: lucifer > Mail: [email protected] > Created Time: 2014年11月14日 星期五 17时43分36秒 ************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> #include <sys/mman.h> #include <string.h> #include <unistd.h> #define N 5 int nthread = 0; struct allocate_task { char *start; char *end; int size; int num; }; void sys_err(const char *str) { perror(str); exit(-1); } void *thread_copy(void *arg) { int i; struct allocate_task *s = (struct allocate_task *)arg; for(i = 0;i < nthread;i++) { memcpy(s[i].end,s[i].start,s[i].size); } } int main(int argc, char *argv[]) { int fdsrc, fddest, i, err, total_size,task_size; struct stat sbuf; char *psrc,*pdest; if(argc < 3) { fprintf(stdout,"%s srcname destname\n",argv[0]); exit(-1); } if(argc = 3) nthread = N; else nthread = atoi(argv[3]); if(stat(argv[1],&sbuf) < 0) sys_err("stat"); total_size = sbuf.st_size; fddest = open(argv[2],O_CREAT |O_RDWR | O_TRUNC,0664); if(fddest < 0) sys_err("open"); if(lseek(fddest,total_size - 1,SEEK_SET) < 0) sys_err("lseek"); write(fddest,"\0",1); fdsrc = open(argv[1],O_RDONLY); if(fdsrc < 0) sys_err("open"); psrc = mmap(NULL,total_size,PROT_READ,MAP_PRIVATE,fdsrc,0); if(psrc == MAP_FAILED) sys_err("mmap"); pdest = mmap(NULL,total_size,PROT_WRITE,MAP_SHARED,fddest,0); if(pdest == MAP_FAILED) sys_err("mmap"); close(fdsrc); close(fddest); struct allocate_task *work = malloc(nthread * sizeof(struct allocate_task)); task_size = total_size / nthread; for(i = 0;i < nthread - 1;i++) { work[i].start = psrc + i * task_size; work[i].end = pdest + i * task_size; work[i].size = task_size; } work[i].start = psrc + i * task_size; work[i].end = pdest + i * task_size; work[i].size = total_size - task_size * (nthread - 1); work[i].num = i; pthread_t tid[nthread]; for(i = 0;i < nthread;i++) { err = pthread_create(&tid[i],NULL,thread_copy,(void *)work); if(err != 0) { printf("%s\n",strerror(err)); break; } } for(i = 0;i < nthread; i++) { pthread_join(tid[i],NULL); } free(work); return 0; }