首页 > 其他分享 >2024.8.1 作业

2024.8.1 作业

时间:2024-08-01 18:54:04浏览次数:14  
标签:return 2024.8 作业 len char int txt ptr

使用两个线程完成两个文件的拷贝,分支线程1拷贝前一半,分支线程2拷贝后一半,主线程回收两个分支线程的资源

代码:

/*******************************************/

文件名:threadwork.c

/*******************************************/

#include <myhead.h>
//创建传输信息的结构体
struct TXT
{
    char *a;
    char *b;
    int key;
};
//定义求源文件大小的函数
int get_file_len(const char *srcfile, const char *destfile)
{
    //以只读的形式打开源文件
    int sfd = open(srcfile, O_RDONLY);
    if (sfd == -1)
    {
        perror("open srcfile error");
        return -1;
    }

    //以创建的形式打开目标文件
    int dfd = open(destfile, O_WRONLY | O_CREAT | O_TRUNC, 0664);
    if (dfd == -1)
    {
        perror("open destfile error");
        return -1;
    }

    int size = lseek(sfd, 0, SEEK_END);

    //关闭文件
    close(sfd);
    close(dfd);

    return size; //将文件大小返回
}

//定义文件拷贝函数
void copy_file(const char *srcfile, const char *destfile, int start, int len)
{
    //以只读的形式打开源文件
    int sfd = open(srcfile, O_RDONLY);
    if (sfd == -1)
    {
        perror("open srcfile error");
        return;
    }

    //以创建的形式打开目标文件
    int dfd = open(destfile, O_WRONLY);
    if (dfd == -1)
    {
        perror("open destfile error");
        return;
    }

    //移动光标位置
    lseek(sfd, start, SEEK_SET);
    lseek(dfd, start, SEEK_SET);

    //定义搬运工
    char buf[128] = "";
    int sum = 0; //记录拷贝的总个数
    while (1)
    {
        //从源文件中读取数据
        int res = read(sfd, buf, sizeof(buf));
        sum += res; //将读取的个数累加

        if (res == 0 || sum > len) //表示文件读取结束
        {
            write(dfd, buf, res - (sum - len)); //父进程将最后一次拷贝结束
            break;
        }
        //写入到目标文件中
        write(dfd, buf, res);
    }

    //关闭文件
    close(sfd);
    close(dfd);
}
void *task(void *arg)
{
    if (arg == NULL)
    {
        return NULL;
    }
    // 将arg转换为struct TXT指针
    struct TXT *txt_ptr = (struct TXT *)arg;
    int len = get_file_len(txt_ptr->a, txt_ptr->b);
    pid_t pid = fork();
    if (txt_ptr->key == 0)
    {
        //线程1拷贝前一半
        copy_file(txt_ptr->a, txt_ptr->b, 0, len / 2);
        pthread_exit(NULL);
    }
    else if (txt_ptr->key == 1)
    {
        //线程2拷贝后一半
        copy_file(txt_ptr->a, txt_ptr->b, len / 2, len - len / 2);
        pthread_exit(NULL);
    }
    else
    {
        printf("load error\n");
    }
}
int main(int argc, char const *argv[])
{
    //判断是否是三个文件
    if (argc != 3)
    {
        write(2, "input file error\n", sizeof("input file error\n"));
        return -1;
    }
    // 使用strdup复制argv中的字符串,因为argv中的字符串是常量
    char *source = strdup(argv[1]);
    char *destination = strdup(argv[2]);
    if (!source || !destination)
    {
        perror("strdup failed");
        // 释放之前可能已经分配的内存
        free(source);
        free(destination);
        return -1;
    }
    //创建结构体接收字符信息
    struct TXT txt1 = {source, destination, 0};
    struct TXT txt2 = {source, destination, 1};
    //创建两个线程
    pthread_t tid1, tid2;
    if (pthread_create(&tid1, NULL, task, &txt1) != 0)
    {
        printf("thread create error\n");
        return -1;
    }
    if (pthread_create(&tid2, NULL, task, &txt2) != 0)
    {
        printf("thread create error\n");
        return -1;
    }
    //阻塞等待线程结束
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    return 0;
}

结果:

思维导图:

标签:return,2024.8,作业,len,char,int,txt,ptr
From: https://blog.csdn.net/sdhdhdhdh/article/details/140854911

相关文章

  • C高级(学习)2024.8.1
    目录shell命令数组数组的赋值数组的调用遍历数组函数函数的定义方式函数调用分文件编程源文件头文件include引用时“”和<>的区别编译工具gcc编译工具gdb调试make工具定义Makefile格式Makefile管理多个文件Makefile变量自定义变量预定义变量自动变量Ma......
  • 【笔记】杂题选讲 2024.8.1 下午
    [AGC018F]TwoTrees[AGC018F]TwoTrees-洛谷|计算机科学教育新生态(luogu.com.cn)先判一下奇偶性。考虑做一个很强的钦定,奇数都填\(\pm1\),偶数都填\(0\)。对于同一棵树的一棵子树,考虑对子树内两个奇数点做匹配,要求匹配上的点一个\(+1\)一个\(-1\),这样就能在子树的根......
  • 【笔记】字符串选讲 2024.8.1
    [COCI2015-2016#5]OOP(Trie)P6727[COCI2015-2016#5]OOP-洛谷|计算机科学教育新生态(luogu.com.cn)正反串分别建Trie,可以搞出两个dfn区间,加之长度限制,三维数点。有\(O(n\logn)\)做法。将字典串\(S[1..m]\),对所有\(1\leqi\leqm\),将\(S[i+1,m]\)的hash值插入......
  • 完美使用 Google Cloud Run:为单个作业中的每个流程创建新的执行 ID
    我目前正在使用Prefect云来编排不同的任务,并且我正在使用CloudRunPush工作池将这些任务作为作业部署在GoogleCloudRun上。这是我面临的情况:每次运行流程时,它都会创建一个新的任务在CloudRun上工作。然而,这不是我想要的行为。相反,我希望每个部署都有一个作业,具有......
  • 将 python 脚本作为 AWS 胶水服务作业运行
    我有一个使用本地路径在本地运行的python脚本,但我需要复制此python脚本并将其作为AWS胶水服务作业运行并将输出保存在s3存储桶中。请帮助我逐步说明。将Python脚本作为AWSGlue作业运行的步骤如下:步骤1:修改的Python脚本以使其与Glue兼容......
  • 作业帮6-19笔试-选填题
    可以看到10在第一位,说明用的是挖坑法快速排序,过程如下:右指针从最右边开始,找到第一个比30小的数10,与30交换。10、15、40、28、50、30、70左指针从位置1开始,找到40,与30互换。10、15、30、28、50、40、70右指针再找到28,与30互换.10、15、28、30、50、40、70左右指针相......
  • html+css+js作业王者荣耀1个页面西施(带js)
    html+css+js作业王者荣耀1个页面西施(带js)下载地址https://download.csdn.net/download/qq_42431718/89595507目录1目录2项目视频html+css+js作业王者荣耀1个页面西施带js页面1......
  • web期末作业设计网页/web前端开发期末大作业/html css网页制作成品(第51-60套/总计100
     博主介绍:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。所有项目都配有从入门到精通的基础知识视频课程,学习后应对毕业设计答辩。项目配有对应开发文档、开题报告、任务书、P......
  • 402.高端大气的网络科技公司网页 大学生期末大作业 Web前端网页制作 html+css+js
    目录一、网页概述二、网页文件 三、网页效果四、代码展示1.html2.CSS3.JS五、总结1.简洁实用2.使用方便3.整体性好4.形象突出5.交互式强六、更多推荐欢迎光临仙女的网页世界!这里有Web前端网页制作的各行各业的案例,样式齐全新颖,并持续更新!感谢CSDN,提供了这......
  • 7.26课后作业
    课堂笔记整理思维导图二、使用fgets统计给定文件的行号intmain(intargc,constchar*argv[]){ intcount=0; FILE*file=fopen("./text.txt","r"); charbuf[20]=""; char*data=fgets(buf,sizeof(buf),file); while(data!=NULL){ intindex=strlen(data......