multithread copy

来源:互联网 发布:山西麻将unity3d源码 编辑:程序博客网 时间:2024/04/30 00:53


#include <iostream>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <cstring>#include <pthread.h>#include <sys/mman.h>using namespace std;struct copyinfo{char *src = NULL;char *dst = NULL;int  len = 0;int  id = 0;};void *thread_do(void *arg){if(arg == NULL){cout << "thread_do() arg==NULL" << endl;return NULL;}struct copyinfo *p = (struct copyinfo *)arg;int i = 0;char *s = p->src;char *d = p->dst;printf("thread_do() tid=%lx, p->id=%d begin copy\n", pthread_self(), p->id);int len = p->id * p->len;while(i < p->len){//write(4, s + i, 1);d[i] = s[i];i++;}printf("thread_do() tid=%lx, p->id=%d finish copy\n", pthread_self(), p->id);return arg;//这里 这个返回参数没什么用。}//using void *(* fun)(void *);class thread{private:char *src = NULL;char *dst = NULL;int  fdsrc = -1;int  fddst = -1;int  threadamount = 0;int  sizeamount = 0;int  sizebatch = 4096;int  sizethread = 0;int  sizethreadlast = 0;char *copy_src = NULL;char *copy_dst = NULL;public:thread(){}thread(const char *s, const char *d, int n){if(s == NULL || d == NULL || n <= 0){cout << "thread(...) call err, s==NULL||d==NULL||c<=0" << endl;return ;}int fd1 = open(s, O_RDONLY);//此时,mmap不能共享映射该文件,但可以以私有方式映射该文件,而当以读写方式打开文件时,就可以共享映射。if(fd1 < 0){cout << "thread(...) call open() err" << endl;perror("thread(...) open");return;}int fd2 = open(d, O_RDWR);if(fd2 < 0){cout << "thread(...) call open() err" << endl;perror("thread(...) open");close(fd1);//此时fd1再打开也是没用的了,所以将其关掉。return;}fdsrc = fd1;fddst = fd2;src = new char[strlen(s) + 1];if(src == NULL){cout << "thread(...) new char[] err" << endl;return;}dst = new char[strlen(d) + 1];if(dst == NULL){cout << "thread(...) new char[] err" << endl;delete []src;//由于dst没有分配成功内存,所以给src分配内存也是没有必要的了。src = NULL;return;}strcpy(src, s);strcpy(dst, d);threadamount = n;int temp = sizebatch % threadamount;if(temp == 0){sizethread = sizebatch / threadamount;sizethreadlast = 0;}else if(temp > 0){sizethread = sizebatch / threadamount;sizethreadlast = sizethread + temp;}elsecout << "thread(...) should not" << endl;}~thread(){cout << "~thread" << endl;if(src){delete []src;src = NULL;}if(dst){delete []dst;dst = NULL;}}int getsrcsize(){if(fdsrc < 0){cout << "getsize() bad fdsrc" << endl;return -1;}int size = lseek(fdsrc, 0, SEEK_END);if(size < 0){perror("getsize() lseek");return -1;}lseek(fdsrc, 0, SEEK_SET);sizeamount = size;return size;}int setdstsize(){if(fddst < 0){cout << "getdstsize() bad fddst" << endl;return -1;}lseek(fddst, 10240, SEEK_SET);//set 10240 temporarywrite(fddst, "a", 1);lseek(fddst, 0, SEEK_SET);}void setinfo_thread(){}void allocate_thread(void *(* operate)(void *), void *info){if(threadamount <= 0){cout << "allocate_thread() threadamount<=0" << endl;return;}pthread_t tid;pthread_attr_t attr;pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);int count = 0;if(sizethreadlast == 0){while(count < threadamount){struct copyinfo *p = new struct copyinfo;p->id = count;p->len = sizethread;p->src = copy_src + p->id * p->len;p->dst = copy_dst + p->id * p->len;pthread_create(&tid, &attr, operate, (void *)p);//printf("allocate_thread(...) pid=%d\t main tid=%lx\t child tid=%lx count=%d\n", getpid(), pthread_self(), tid, count);//sleep(1);count++;}}else if(sizethreadlast > 0){while(count < threadamount - 1){struct copyinfo *p = new struct copyinfo;p->id = count;p->len = sizethread;p->src = copy_src + p->id * p->len;p->dst = copy_dst + p->id * p->len;pthread_create(&tid, &attr, operate, (void *)p);//printf("allocate_thread(...) pid=%d\t main tid=%lx\t child tid=%lx count=%d\n", getpid(), pthread_self(), tid, count);//sleep(10);count++;}struct copyinfo *p = new struct copyinfo;p->id = count;p->len = sizethreadlast;p->src = copy_src + p->id * p->len;p->dst = copy_dst + p->id * p->len;pthread_create(&tid, &attr, operate, (void *)p);//printf("allocate_thread(...) pid=%d\t main tid=%lx\t child tid=%lx count=%d\n", getpid(), pthread_self(), tid, count);//sleep(10);count++;}elsecout << "allocate_thread() call should not" << endl;//while(1);pthread_exit((void *)pthread_self());return;}int isvalid(){int flg = 0;if(src == NULL)flg = 1;if(dst == NULL)flg = 2;if(fdsrc < 0)flg = 3;if(fddst < 0)flg = 4;if(threadamount <= 0)flg = 5;if(sizeamount < 0)flg = 6;if(sizebatch <= 0)flg = 7;if(sizethread <= 0)flg = 8;return flg;}void mapping(){int err = 0;if(err = isvalid()){cout << "mapping() thread unvalid : " << err << endl;return;}char *memsrc = (char *)mmap(NULL, sizebatch, PROT_READ, MAP_PRIVATE, fdsrc, 0);//私有映射时,对应的文件可以是只读打开的,如果是共享映射的,则对应的文件应当是读写打开,否则mmap不成功。//cout << "*********************************************" << endl;//printf("%s,|,|,| %d,|%c~~~~~~~srcfile~~~~~~~~\n", memsrc, strlen(memsrc), *memsrc);if(memsrc == MAP_FAILED){perror("mmap");cout << "mapping() mmap" << endl;return;}copy_src = memsrc;char *memdst = (char *)mmap(NULL, sizebatch, PROT_READ|PROT_WRITE, MAP_SHARED, fddst, 0);//私有映射时,对应的文件可以是只读打开的,如果是共享映射的,则对应的文件应当是读写打开,否则mmap不成功。if(memdst == MAP_FAILED){perror("mmap");cout << "mapping() mmap" << endl;return;}copy_dst = memdst;//cout << "copy_dst = " << copy_dst << endl;//printf("%s,|,|,| %d,|%c~~~~~~~~dstfile~~~~~~~\n", memdst, strlen(memdst), *memdst);//while(1);//cout << mem << endl;//cout << mem+1 << endl;//cout << mem+2 << endl;}void show(){if(src != NULL)cout << "src = " << src << endl;if(dst != NULL)cout << "dst = " << dst << endl;cout << "fdsrc = " << fdsrc << endl;cout << "fddst = " << fddst << endl;cout << "threadamount = " << threadamount << endl;cout << "sizeamount = " << sizeamount << endl;cout << "sizebatch = " << sizebatch << endl;cout << "sizethread = " << sizethread << endl;cout << "sizethreadlast = " << sizethreadlast << endl;}char *getcopy_src(){return copy_src;}char *getcopy_dst(){return copy_dst;}int getcopy_len(){return sizethread; }int getfddst(){return fddst;}};int main(int argc, char *argv[]){if(argc < 4){cout << "./a.out src dst amount" << endl;exit(1);}thread th(argv[1], argv[2], atoi(argv[3]));th.setdstsize();cout << th.getsrcsize() << endl;th.setdstsize();th.show();th.mapping();struct copyinfo info;info.src = th.getcopy_src();//info.len = th.getcopy_len();info.dst = th.getcopy_dst();th.allocate_thread(thread_do, (void *)&info);return 0;}



0 0
原创粉丝点击