一、思维导图二、练习使用两个线程完成两个文件的拷贝分支线程1拷贝前一半分支线程2拷贝后一半主线程回收两个分支线程的资源#includemyhead.h //定义结构体存储需要传到线程函数中的内容 struct Buf { const char *file[2]; //存储源文件和目标文件文件名 int start; //拷贝开始位置 int len; //存储需要拷贝的长度 }; void *copy(void *buf) { //判断传过来的信息 //前半部分拷贝 //解引用结构体参数 int start ((struct Buf*)buf)-start; int len ((struct Buf*)buf)-len; const char *src ((struct Buf*)buf)-file[0]; const char *dest ((struct Buf*)buf)-file[1]; //打开源文件和目标文件描述符 int sfd open(src,O_RDONLY); if(-1 sfd) { perror(open src error); } int dfd open(dest,O_WRONLY); if(-1 dfd) { perror(open dest error); } //根据参数判断拷贝部分 if(start 0) { //线程1执行的内容 //拷贝前一半 printf(1start %d,len %d\n,start,len); //移动文件光标 lseek(sfd,start,SEEK_SET); lseek(dfd,start,SEEK_SET); } //后半部分拷贝 else if(start ! 0) { //线程2执行的内容 //拷贝后一半 printf(2start %d,len %d\n,start,len); //移动文件光标 lseek(sfd,start,SEEK_SET); lseek(dfd,start,SEEK_SET); } //定义拷贝容器 char Cop[128]; int sum 0; //累加拷贝的字节数量 while(1) { int res read(sfd,Cop,sizeof(Cop)); sum res; //将读取的个数累加 if(res0 || sumlen) { write(dfd,Cop,res-(sum-len)); //前半部分最后一次拷贝写入到目标文件中 break; } //写入到目标文件中 write(dfd,Cop,res); } printf(拷贝成功\n); //退出线程 pthread_exit(NULL); } int main(int argc, const char *argv[]) { //判断终端数入 if(argc ! 3) { printf(input error\n); printf(usage:./a.out srcfile destfile\n); return -1; } //打开源文件和目标文件描述符 int sfd open(argv[1],O_RDONLY); if(-1 sfd) { perror(open src error); return -1; } int dfd open(argv[2],O_WRONLY|O_CREAT|O_TRUNC,0664); if(-1 dfd) { perror(open dest error); return -1; } //计算出源文件长度以及线程2拷贝开始位置 int len lseek(sfd,0,SEEK_END); printf(len %d\n,len); //关闭文件 close(sfd); close(dfd); //定义两个容器分别传输两个线程的参数 struct Buf buf1 {{argv[1],argv[2]},0,len/2}; struct Buf buf2 {{argv[1],argv[2]},len/2,len-len/2}; //定义线程变量 pthread_t tid1,tid2; //创建两个线程 if(pthread_create(tid1,NULL,copy,buf1) ! 0) { printf(tid1创建失败\n); return -1; } if(pthread_create(tid2,NULL,copy,buf2) ! 0) { printf(tid2创建失败\n); return -1; } //阻塞等待线程的结束 pthread_join(tid1,NULL); pthread_join(tid2,NULL); return 0; }