使用多线程完成两个文件的拷贝,分支线程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];
//创建分支线程1
pthread_t tid1;
pthread_create(&tid1,NULL,task1,&buf);
//创建分支线程2
pthread_t tid2;
pthread_create(&tid2,NULL,task2,&buf);
//等待线程结束
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
return 0;
}
思维导图