使用两个线程完成两个文件的拷贝,分支线程1完成前一半内容拷贝,分支线程2完成后一半内容的拷贝,主线程完成资源的回收
#include <myhead.h>
//定义全局变量,方便进入不同线程
pthread_t tid1=-1;
pthread_t tid2=-1;
//定义结构体,方便主线程向子线程,传多个不同参数
typedef struct
{
char p[20];
char q[20];
int len;
}ok;
//求文件1字节大小,顺便创建文件2
int lengh(const char *src,const char *dest)
{
int fd1=-1;
if((fd1=open(src,O_RDONLY))==-1)
{
perror("open fd1");
return -1;
}
int fd2=-1;
if((fd2=open(dest,O_RDWR|O_CREAT|O_TRUNC,0664))==-1)
{
perror("open fd2");
return -1;
}
close(fd1);
close(fd2);
//文件1的光标移动到结尾,返回值为文件大小
int len=lseek(fd1,0,SEEK_END);
return len;
}
//文件拷贝
int kb(const int fd1,const int fd2,int strat,int len)
{
//两个文件的光标都移动到同一位置
lseek(fd1,strat,SEEK_SET);
lseek(fd2,strat,SEEK_SET);
char a[10]="";
int res=0;
int n=0;
while(1)
{
res=read(fd1,a,sizeof(a));
n+=res;
//如果读到指定位置或者到结尾,退出循环
if(n==len||res<=0)
{
write(fd2,a,res-(n-len));
break;
}
write(fd2,a,res);
}
return 0;
}
void *task(void *arg)
{
//将通用类型指针强转为结构体类型指针
ok o=*(ok*)arg;
//退出线程
//读文件1
int fd1=-1;
if((fd1=open(o.p,O_RDONLY))==-1)
{
perror("open fd1");
// return;
}
//写文件2
int fd2=-1;
if((fd2=open(o.q,O_WRONLY))==-1)
{
perror("open fd2");
// return;
}
int n=o.len;
pthread_t tid=pthread_self();
//进入线程1
if(tid==tid1)
{
puts("进入线程1");
//调用函数kd
kb(fd1,fd2,0,n/2);
close(fd1);
close(fd2);
puts("线程1结束");
//退出线程
pthread_exit(NULL);
}
//进入线程2
if(tid==tid2)
{
puts("进入线程2");
//调用函数kd
kb(fd1,fd2,n-n/2,n-n/2);
close(fd1);
close(fd2);
puts("线程2结束");
//退出线程
pthread_exit(NULL);
}
}
int main(int argc, const char *argv[])
{
if(argc!=3)
{
puts("输入错误,请重新输入.");
return -1;
}
//定义结构体变量,为其赋值
ok o;
strcpy(o.p,argv[1]);
strcpy(o.q,argv[2]);
o.len=lengh(argv[1],argv[2]);
//创建线程1
if(pthread_create(&tid1,NULL,task,&o)!=0)
{
printf("creat tid1 error\n");
return -1;
}
//创建线程2
if(pthread_create(&tid2,NULL,task,&o)!=0)
{
printf("creat tid2 error\n");
return -1;
}
//以阻塞状态回收线程资源
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
puts("文件拷贝结束");
return 0;
}