0801作业+梳理

一、作业

用两个线程完成文件的拷贝

代码:

#include<myhead.h>
int main(int argc, const char *argv[])
{
    //定义变量接受进程号
    pid_t pid = fork();
    if(pid > 0)
    {
        //这是父进程
        pid_t pid1 = fork();
        if(pid1>0)
        {
            printf("我是父进程\n");
        }else if(pid1==0)
        {
            printf("我是小儿子\n");
            //退出进程
            sleep(8);
            printf("second die\n");
            exit(EXIT_SUCCESS);
        }else
        {
            perror("fork error");
            return -1;
        }
    }else if(pid == 0)
    {
        printf("我是老大\n");
        //退出进程
        sleep(5);
        printf("first die\n");
        exit(EXIT_SUCCESS);
    }else
    {
        perror("fork error");
        return -1;
    }
    //阻塞回收子进程资源
    wait(NULL);
    wait(NULL);

    printf("wohaihuozhe\n");
    sleep(3);
    return 0;
}
ubuntu@ubuntu:0801$ cat 07thread.c 
#include<myhead.h>

//传入子进程函数的数据结构体
struct Buf
{
    const char *pd1;//源文件
    const char *pd2;//目标文件
    int len;//文件长度
    char x;//判断是哪个子进程
};

//求文件长度函数
int line(const char *pd1,const char *pd2)
{
    int fd1 = -1;
    int fd2 = -1;
    //以只读的形式打开源文件
    if((fd1 = open(pd1,O_RDONLY))==-1)
    {
        perror("open fd1 error");
        return -1;
    }
    //以创建的形式打开目的文件
    if((fd2 = open(pd2,O_WRONLY|O_CREAT|O_TRUNC,0664))==-1)
    {
        perror("open fd2 error");
        return -1;
    }
    //求出源文件长度
    int len = 0;
    len = lseek(fd1,0,SEEK_END);
    //关闭文件
    close(fd1);
    close(fd2);
    //返回文件长度
    return len;
}

//定义一个拷贝函数
void copy(const char *pd1,const char *pd2,int start,int len)
{
    int fd1 = -1;
    int fd2 = -1;
    //以只读的形式打开源文件
    if((fd1 = open(pd1,O_RDONLY))==-1)
    {
        perror("open fd1 error");
        return ;
    }
    //以只写的形式打开目的文件
    if((fd2 = open(pd2,O_WRONLY))==-1)
    {
        perror("open fd2 error");
        return ;
    }
    //光标位置
    lseek(fd1,start,SEEK_SET);
    lseek(fd2,start,SEEK_SET);
    //定义搬运工
    char buf[128] = "";
    int res = 0;
    int sum = 0;
    //拷贝
    while(1)
    {
        res = read(fd1,buf,sizeof(buf));
        sum += res; //读取字节个数累加
        if(res ==0||sum>len)//不在读取文件
        {
            write(fd2,buf,res-sum+len);//把最后一次读取进来的拷贝进进行前半段拷贝的子进程中
            break;
        }
        write(fd2,buf,res);
    }
    //结束文件
    close(fd1);
    close(fd2);

    return ;
}

//执行拷贝的两个子进程函数
void *task(void *arg)
{
    //把传入子进程的数据导出
    const char*fd1 = (*((struct Buf*)arg)).pd1;
    const char*fd2 = (*((struct Buf*)arg)).pd2;
    int len = (*((struct Buf*)arg)).len;
    char x = (*((struct Buf*)arg)).x;
    //判断传过来的信息
    if(x=='a')
    {
        //线程1执行的内容
        //利用拷贝函数拷贝前半段内容
        copy(fd1,fd2,0,len/2);
        //退出子进程
        pthread_exit(NULL);
    }else if(x=='b')
    {
        //线程2执行的内容
        //利用拷贝函数拷贝后半段内容
        copy(fd1,fd2,len/2,len-len/2);
        //退出子进程
        pthread_exit(NULL);
    }else
    {
        printf("pthread_create error\n");
    }
}

/***************主函数**************/
int main(int argc, const char *argv[])
{
    //判断传入是否为2个文件
    if(argc !=3)
    {
        printf("input file error\n");
        return -1;
    }
    //使用求文件长度函数得到文件长度
    int len = 0;
    len = line(argv[1],argv[2]);
    //定义结构体传入子线程
    struct Buf buf1 = {argv[1],argv[2],len,'a'};
    struct Buf buf2 = {argv[1],argv[2],len,'b'};
    //定义线程变量
    pthread_t tid1,tid2;
    //创建两个线程
    if(pthread_create(&tid1,NULL,task,&buf1)!=0)
    {
        printf("tid1 创建失败\n");
        return -1;
    }
    if(pthread_create(&tid2,NULL,task,&buf2)!=0)
    {
        printf("tid2 创建失败\n");
        return -1;
    }
    //阻塞等待线程的结束
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);

    printf("拷贝成功\n");
    return 0;
}

运行结果:

二、思维导图(线程)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值