1.思维导图:
2.作业:使用多线程拷贝同一份文件,线程1拷贝前一半,线程2拷贝后一半,主线程阻塞等待回收子线程的资源
/*使用多线程拷贝同一份文件,线程1拷贝前一半,线程2拷贝后一半,主线程阻塞等待回收子线程的资源*/
#include<myhead.h>
#include <pthread.h>
typedef struct Filename
{
char *sf;
char *df;
int start;
int len;
}filename;
int get_len(const char *srcfile, const char *destfile)
{
//定义两个文件描述符
int fd1, fd2;
//以只读的形式打开第一个文件
if((fd1=open(srcfile, O_RDONLY)) == -1)
{
perror("open srcfile error");
return -1;
}
//以读写的形式打开文件
if((fd2 = open(destfile, O_RDWR|O_CREAT|O_TRUNC, 0664)) == -1)
{
perror("open destfile error");
return -1;
}
//求源文件的大小
int len = lseek(fd1, 0, SEEK_END);
//关闭两个文件
close(fd1);
close(fd2);
return len;
}
//定义拷贝函数
int copy_file( const char *srcfile, const char *destfile, int start, int len)
{
//定义两个文件描述符
int fd1, fd2;
//以只读的形式打开第一个文件
if((fd1=open(srcfile, O_RDONLY)) == -1)
{
perror("open srcfile error");
return -1;
}
//以读写的形式打开文件
if((fd2 = open(destfile, O_RDWR)) == -1)
{
perror("open destfile error");
return -1;
}
//定位两个文件的光标
lseek(fd1, start, SEEK_SET);
lseek(fd2, start, SEEK_SET);
//拷贝工作
char buf[128] = ""; //内容搬运工
int ret = 0;
int count = 0; //记录读取的个数
while(1)
{
//从源文件中读取数据
ret = read(fd1, buf, sizeof(buf));
count += ret; //将读取的个数累加
if(ret == 0 || count > len)
{
write(fd2, buf, ret - (count-len)); //最后一次写操作
break;
}
//将读取下来的内容写到新文件中去
write(fd2, buf, ret);
}
close(fd1);
close(fd2);
return 0;
}
//子线程处理函数
void *task1(void *arg)
{
printf("这是子线程1...\n");
filename *fn = (filename *)arg;
copy_file(fn->sf,fn->df,fn->start,fn->len);
printf("子线程1结束\n");
pthread_exit(NULL);
}
int main(int argc,const char *argv[])
{
//判断传递的文件个数
if(argc != 3)
{
printf("input file error\n");
printf("usage:./a.out srcfile destfile\n");
return -1;
}
//求原文件长度顺便创建目标文件
int len = get_len(argv[1], argv[2]);
//给结构体赋值
filename fn1 ={.sf = argv[1],.df = argv[2],.start = 0,.len = len/2};
filename *fp1 = &fn1;
filename fn2 ={.sf = argv[1],.df = argv[2],.start = len/2,.len =len - len/2};
filename *fp2 = &fn2;
//定义线程号
pthread_t tid1,tid2;
if(pthread_create(&tid1,NULL,task1,fp1)){
perror("create pthread1");//错误信息
return -1;
}
if(pthread_create(&tid2,NULL,task1,fp2)){
perror("create pthread2");//错误信息
return -1;
}
//阻塞给子线程收尸
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
}
输出: