Linux多进程和多线程拷贝文件

多进程实现文件拷贝

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

int main(int argc, char *argv[])
{
    int n = 5;
    if(argc < 3)
    {
        printf("./a.out src dst [n]\n");
        return -1;
    }
    if(argc==4)
    {
        n = atoi(argv[3]);
    }
    int srcfd = open(argv[1], O_RDONLY);
    if(srcfd < 0)
    {
        perror("open src");
        exit(1);
    }
    int dstfd = open(argv[2], O_RDWR|O_CREAT|O_TRUNC,0664);
    if(dstfd < 0)
    {
        perror("open dst");
        exit(1);
    }
    struct stat sb;
    stat(argv[1], &sb);
    int len = sb.st_size;
    truncate(argv[2], len);
    
    char *psrc = mmap(NULL, len, PROT_READ, MAP_SHARED, srcfd,0);
    if(psrc == MAP_FAILED)
    {
        perror("mmap src");
        exit(1);
    }
    char *pdst= mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, dstfd, 0);
    if(pdst == MAP_FAILED)
    {
        perror("mmap dst");
        exit(1);
    }
    int i = 0;
    for(i = 0; i < n; i++)
    {
        if(fork() == 0)
        {
            break;
        }
    }

    int cpsize = len / n;
    int mod = len % n;
    
    if(i < n)
    {
        if(i == n-1)
        {
            memcpy(pdst+i*cpsize, psrc+i*cpsize, cpsize+mod);
        }
        else
        {
            memcpy(pdst+i*cpsize, psrc+i*cpsize, cpsize);
        }
    }
    else
    {
        for(i = 0; i < n; i++)
        {
            wait(NULL);
        }
    }
    if(munmap(psrc, len) < 0)
    {
        perror("munmap src");
        exit(1);
    }
    if(munmap(pdst, len) < 0)
    {
        perror("munmap dst");
        exit(1);
    }
    close(srcfd);
    close(dstfd);
    return 0;
}

多线程实现文件拷贝

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

#define _THR_CNT_ 5

typedef struct _TaskInfo{
    int num;
    void *src;
    void *des;
    int size;
}TaskInfo;

void *thr_cp(void* arg)
{
    TaskInfo *info = arg;
    int num = info -> num;
    int cpsize = info -> size / _THR_CNT_;
    int mod = info -> size % cpsize;
    if(num == _THR_CNT_ - 1)
    {
        memcpy(info -> des + num * cpsize, info -> src + num * cpsize, cpsize+mod);
    }
    else
    {
        memcpy(info -> des + num * cpsize, info -> src + num * cpsize, cpsize);
    }
    return NULL;
}

int main(int argc, char *argv[])
{
    if(argc != 3)
    {
        printf("./a.out srcfile desfile\n");
        return -1;
    }
    int n = _THR_CNT_;
    struct stat sb;
    if(stat(argv[1], &sb) < 0)
    {
        perror(argv[1]);
        exit(1);
    }
    long lfilesize = sb.st_size;

    int fdsrc = open(argv[1], O_RDONLY);
    int fddes = open(argv[2], O_RDWR|O_CREAT|O_TRUNC, 0666);
    ftruncate(fddes, lfilesize);
    
    if(fdsrc < 0 || fddes < 0)
    {
        printf("open file %s %s error\n", argv[1], argv[2]);
        exit(1);
    }

    void *srcmem = mmap(NULL, lfilesize, PROT_READ, MAP_PRIVATE, fdsrc, 0);
    if(srcmem == MAP_FAILED)
    {
        perror("mmap srcfile");
        exit(1);
    }
    void *desmem = mmap(NULL, lfilesize, PROT_READ|PROT_WRITE, MAP_SHARED, fddes, 0);
    if(desmem == MAP_FAILED)
    {
        perror("mmap desfile");
        exit(1);
    }

    TaskInfo taskInfos[_THR_CNT_];
    pthread_t tid[_THR_CNT_];
    int i;
    for(i = 0; i < n; i++)
    {
        taskInfos[i].src = srcmem;
        taskInfos[i].des = desmem;
        taskInfos[i].num = i;
        taskInfos[i].size = lfilesize;
        pthread_create(&tid[i], NULL, thr_cp, &taskInfos[i]);
    }
    for(i = 0; i < n; i++)
    {
        pthread_join(tid[i], NULL);
    }
    munmap(srcmem, lfilesize);
    munmap(desmem, lfilesize);
    return 0;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值