使用多线程完成两个文件的拷贝,分支线程1,拷贝前一半,分支线程2拷贝后一半,主线程用于回收分支线程的资源
#include <myhead.h>
//声明全局变量
pthread_mutex_t mutex; //互斥锁
int source = -1; //源文件描述符
int dest = -1; //目标文件描述符
int len = 0; //源文件总长度
int half_len = 0; //源文件的一半长度
//线程1 负责拷贝源文件的前半部分
void *task1(void *arg)
{
char rbuf[128] = ""; //用于存储读取的数据的缓冲区
lseek(source, 0, SEEK_SET); //设置源文件指针到文件开头
int sum = 0; //设置读取的字节总数
while(sum < half_len) //循环读取直到读取的字节数达到文件的一半
{
pthread_mutex_lock(&mutex); //加锁 防止其他线程干扰文件操作
int res = read(source, rbuf, sizeof(rbuf)); //读取数据到缓冲区
if(res == 0) //如果读取到文件末尾 退出循环
{
pthread_mutex_unlock(&mutex); //解锁
break;
}
sum += res; //更新已读取的字节总数
if(sum > half_len) //如果超过文件的一半 仅写入多余部分 避免越界写入
{
write(dest, rbuf, res - (sum - half_len)); //写入目标文件的剩余部分
}
else
{
write(dest, rbuf, res); //写入读取的完整数据
}
pthread_mutex_unlock(&mutex); //解锁 允许其他线程操作
}
pthread_exit(NULL); //线程结束
}
//线程2 负责拷贝源文件的后半部分
void *task2(void *arg)
{
char rbuf[128] = ""; //用于存储读取的数据的缓冲区
lseek(source, half_len, SEEK_SET); //设置源文件指针到文件的中间位置
int res;
while(1)
{
pthread_mutex_lock(&mutex); //加锁 防止其他线程干扰文件操作
res = read(source, rbuf, sizeof(rbuf)); //读取数据到缓冲区
if(res == 0) //如果读取到文件末尾 退出循环
{
pthread_mutex_unlock(&mutex); //解锁
break;
}
write(dest, rbuf, res); //将读取的数据写入目标文件
pthread_mutex_unlock(&mutex); //解锁,允许其他线程操作
}
pthread_exit(NULL); //线程结束
}
int main(int argc, const char *argv[])
{
pthread_mutex_init(&mutex, NULL); //初始化互斥锁
//打开源文件 只读模式
if((source=open("./source.txt",O_RDONLY))==-1)
{
perror("open source error"); //打开失败 输出错误信息
return -1;
}
//打开目标文件 写模式 如果不存在则创建 存在则清空内容
if((dest = open("dest.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664)) == -1)
{
perror("open dest error"); //打开失败,输出错误信息
close(source); //关闭已打开的源文件
return -1;
}
//获取源文件的长度
len = lseek(source, 0, SEEK_END);
if(len == -1)
{
perror("lseek error"); //获取文件长度失败 输出错误信息
close(source); //关闭源文件
close(dest); //关闭目标文件
return -1;
}
//计算源文件的一半长度
half_len = (len + 1) / 2;
//创建线程1 负责拷贝前半部分
pthread_t tid1, tid2;
if(pthread_create(&tid1, NULL, task1, NULL) != 0)
{
printf("tid1 create error\n");
return -1;
}
//创建线程2 负责拷贝后半部分
if(pthread_create(&tid2, NULL, task2, NULL) != 0)
{
printf("tid2 create error\n");
return -1;
}
//打印线程的ID 便于调试
printf("tid1 = %#lx, tid2 = %#lx\n", tid1, tid2);
//等待线程1 线程2 执行结束
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_mutex_destroy(&mutex); //销毁互斥锁
close(source); //关闭源文件
close(dest); //关闭目标文件
printf("拷贝成功\n");
return 0;
}

719

被折叠的 条评论
为什么被折叠?



