使用多线程完成两个文件的拷贝,分支线程1,拷贝前一半,分支线程2拷贝后一半,主线程用于回收分支线程的资源
#include<myhead.h>typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;
//定义结构用来保存源文件路径、目标文件路径、源文件长度
typedef struct {const char *src; // 源文件路径const char *dest; // 目标文件路径int len;
}arr;
//获取源文件字节数
int get_file_len(const char* file1,const char* file2)
{//打开源文件int fd1 = open(file1,O_RDONLY);//判断是否打开成功if(fd1==-1){perror("open error");return -1;}//顺便创建目标文件int fd2 = open(file2,O_WRONLY|O_TRUNC|O_CREAT,0664);//判断是否创建成功if(fd2==-1){perror("open error");return -1;}//将光标偏移到文件末尾获取文件长度int len = lseek(fd1,0,SEEK_END);//关闭文件close(fd1);close(fd2);return len;
}//拷贝文件
int copy_file(const char* file1,const char* file2,int start,int len)
{//以只读形式打开源文件int fd1 = open(file1,O_RDONLY);if(fd1==-1){perror("open error");return -1;}//以只写形式打开目标文件int fd2=open(file2,O_WRONLY);//将光标偏移到需要写入数据的位置lseek(fd1,start,SEEK_SET);lseek(fd2,start,SEEK_SET);//定义字符数组用于存储数据char buf[100]="";//用于计算拷贝的字节数int sum=0;int pid = getpid();while(1){//清空容器,防止覆盖不完全bzero(buf,sizeof(buf));//获取每次读取的字节数int res = read(fd1,buf,sizeof(buf));sum += res;//将最后一次读取的数据写入目标文件if(res==0||sum>=len){write(fd2,buf,res-(sum-len));break;}//读多少写多少write(fd2,buf,res);}//关闭文件close(fd1);close(fd2);
}
//分支线程1
void* task1(void* arg)
{//获取传递来的数据arr buf=*(arr *)arg;printf("分支线程1线程号为:%#lx\n",pthread_self());//拷贝前一半数据copy_file(buf.src,buf.dest,0,(buf.len)/2);//结束进程pthread_exit(0);
}//分支线程2
void* task2(void *arg)
{//获取传递的数据arr buf=*(arr *)arg;printf("分支线程2线程号为:%#lx\n",pthread_self());//拷贝后一半数据copy_file(buf.src,buf.dest,(buf.len)/2,buf.len-(buf.len)/2);//结束进程pthread_exit(0);
}int main(int argc, const char *argv[])
{//定义结构体类型变量arr buf;//源文件长度buf.len=get_file_len(argv[1],argv[2]);buf.src=argv[1];buf.dest=argv[2];//创建分支线程1pthread_t tid1;pthread_create(&tid1,NULL,task1,&buf);//创建分支线程2pthread_t tid2;pthread_create(&tid2,NULL,task2,&buf);//等待线程结束pthread_join(tid1,NULL);pthread_join(tid2,NULL);return 0;
}
思维导图