apue学习之多线程拷贝文件

apue学习之多线程拷贝文件

这是一个与多线程相关的小练习,顺带可以复习文件属性,内存映射的知识,代码如下,注释详尽。

// File Name: multithread_copy.c
// Author: AlexanderGan
// Created Time: Mon 29 Jun 2020 03:41:20 PM CST

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<pthread.h>
#include<sys/mman.h>

#define THR_NUM  6  //线程数量
typedef struct _TaskInfo{
    int num;//线程序号
    void* src;//源地址
    void* dst;//目的地址
    int size;//文件尺寸
}TaskInfo;

void* multithread_copy(void* arg)
{
    TaskInfo *info = arg;
    int num = info->num;
    int cpsize = info->size / THR_NUM;
    int mod = info->size % cpsize;//平分后余下的部分
    if (num == THR_NUM -1){
        //如果是最后一个线程需要处理自己的+余下的部分
        memcpy(info->dst+num*cpsize,info->src+num*cpsize,cpsize+mod);
    }
    else{
        memcpy(info->dst+num*cpsize,info->src+num*cpsize,cpsize);
    }
    return NULL;
}
int main(int argc, char* argv[]){
    if(argc != 3){
    //如果参数不足
        printf("please input srcfilename dstfilename!\n");
        return -1;
    }

    struct stat fileinfo;//文件信息结构体apue,p75
    if(stat(argv[1],&fileinfo) < 0)//stat函数获取结构体信息
    {
        perror("argv1 error!\n");
        exit(-1);
    }

    long filesize = fileinfo.st_size;//获取文件大小
    
    int srcfd = open(argv[1],O_RDONLY);
    int dstfd = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0664);
    ftruncate(dstfd,filesize);//文件截断,apue,p90

    if(srcfd < 0 || dstfd < 0){
        printf("open srcfile, dstfile error!\n");
        exit(-1);
    }
    void* srcmem = mmap(NULL,filesize,PROT_READ,MAP_PRIVATE,srcfd,0);//源文件映射
    if(srcmem == MAP_FAILED)
    {
        perror("mmap srcfile error!\n");
        exit(-1);
    }
    void* dstmem = mmap(NULL,filesize,PROT_WRITE,MAP_SHARED,dstfd,0);//目标文件映射
    if(dstmem == MAP_FAILED)
    {
        perror("mmap dstfile error!\n");
        exit(-1);
    }
    TaskInfo tinf[THR_NUM];
    pthread_t tid[THR_NUM];
    int i;
    for(i = 0; i < THR_NUM;i++)//把映射的地址传给线程处理
    {
        tinf[i].src = srcmem;
        tinf[i].dst = dstmem;
        tinf[i].num = i;
        tinf[i].size = filesize;
        pthread_create(&tid[i],NULL,multithread_copy,&tinf[i]);//线程创建,apue,p309
    }
    for(i = 0; i< THR_NUM;i++){
        pthread_join(tid[i],NULL);//回收线程
    }
    close(srcfd);//关闭文件描述符
    close(dstfd);
    munmap(srcmem,filesize);//取消映射
    munmap(dstmem,filesize);
  return 0 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值