使用多线程完成两个文件的拷贝,第一个线程拷贝前一半,第二个线程拷贝后一半,主线程回收两个线程的资源
#include <myhead.h>
//定义结构体用于向两个分支线程传递参数
struct file
{
char *srcfile;
char *destfile;
int start;
int len;
};
//获取源文件的大小并创建一个副本文件
int get_file_len(const char *srcfile, const char *destfile)
{
//以只读的形式打开源文件
int srcfd,destfd;
if((srcfd=open(srcfile, O_RDONLY)) == -1)
{
perror("open srcfile error");
return -1;
}
//以只写创建的形式打开目标文件
if((destfd=open(destfile, O_WRONLY|O_CREAT|O_TRUNC, 0664))==-1)
{
perror("open destfile error");
return -1;
}
//求源文件的大小
int len = lseek(srcfd, 0, SEEK_END);
//关闭两个文件
close(srcfd);
close(destfd);
return len;
}
//定义文件拷贝函数
void *task(void *arg)
{
//处理主线程中传递过来的参数
struct file buf=*((struct file *)arg);
//以只读的形式打开源文件,以只写的形式打开副本文件
int srcfd,destfd;
if((srcfd=open(buf.srcfile, O_RDONLY))==-1)
{
perror("open srcfile error");
}
if((destfd=open(buf.destfile, O_WRONLY))==-1)
{
perror("open destfile error");
}
//移动文件的光标
lseek(srcfd, buf.start, SEEK_SET);
lseek(destfd, buf.start, SEEK_SET);
//完成拷贝工作
char str[128] = "";
int sum = 0;
while(1)
{
int res = read(srcfd,str, sizeof(str));
sum += res; //将每次读取的数据放入sum中
if( sum>=buf.len ||res == 0)
{
write(destfd,str, res-(sum-buf.len)); //将最后一次的内容写入
break;
}
//将读取的数据写入目标文件
write(destfd,str, res);
}
//关闭文件
close(srcfd);
close(destfd);
//退出当前的线程
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
//初始化结构体变量buf1
char *srcfile="./1.bmp";//源文件
char *destfile="./work1.bmp";//副本文件
//定义变量获取源文件的长度并创建一个副本文件
int len=get_file_len(srcfile,destfile);
int start1=0;
struct file buf1={srcfile,destfile,start1,len/2};
//初始化结构体变量buf2
int start2=len/2;
struct file buf2={srcfile,destfile,start2,len-len/2};
//创建分支线程1,并传递结构体buf1
pthread_t tid1;
if(pthread_create(&tid1,NULL,task,&buf1)!=0)
{
printf("tid1 create error\n");
return -1;
}
//回收线程1退出的资源,阻塞等待对应的线程1退出
if(pthread_join(tid1, NULL) == 0)
{
printf("成功回收了线程1\n");
}
//创建分支线程2,并传递结构体buf2
pthread_t tid2;
if(pthread_create(&tid2,NULL,task,&buf2)!=0)
{
printf("tid2 create error\n");
return -1;
}
//回收线程2退出的资源,阻塞等待对应的线程2退出
if(pthread_join(tid2, NULL) == 0)
{
printf("成功回收了线程2\n");
}
printf("拷贝成功\n");
return 0;
}
效果图:
思维导图: