Linux下文件的多进程拷贝

大文件拷贝

假设有一个超大文件,需对其完成拷贝工作。为提高效率,可采用多进程并行拷贝的方法来实现。假设文件 大小为 len,共有 n 个进程对该文件进行拷贝。那每个进程拷贝的字节数应为 len/n。但未必一定能整除,我们可 以选择让最后一个进程负责剩余部分拷贝工作。可使用 len%(len/n)将剩余部分大小求出。
为降低实现复杂度,可选用 mmap 来实现源、目标文件的映射,通过指针操作内存地址,设置每个进程拷贝 的起始、结束位置。借助 MAP_SHARED 选项将内存中所做的修改反映到物理磁盘上

#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;
    //输入参数至少是3,第四个参数可以是进程个数
    if(argc<3){
        printf("./a.out src dst [n]\n");
        return 0;
    }                                                                              
    if(argc==4){
        n=atoi(argv[3]);
    }   
    //打开源文件
    int srcfd=open(argv[1],O_RDONLY);
    if(srcfd<0){
        perror("open err");
        exit(1);
    }   
    //打开目标文件
    int dstfd=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0644);
    if(dstfd<0){
        perror("open dst err");
        exit(1);
    }   
    //目标拓展,从原文件获得文件大小,stat
    struct stat sb; 
    stat(argv[1],&sb);//为了计算大小
    int len=sb.st_size;
    truncate(argv[0],len);
    //将源文件映射到缓冲区
    char *psrc = mmap(NULL,len,PROT_READ,MAP_SHARED,srcfd,0);
if(psrc == MAP_FAILED){
        perror("mmap dst err");
        exit(1);
    }
    //将目标文件映射
    char *pdst = mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,dstfd,0);
    if(pdst == MAP_FAILED){
        perror("mmap dst err");
        exit(1);
    }
    //创建多个子进程
    int i=0;
    for(i=0;i<n;i++)
    {
        if(fork()==0)
            break;
    }
    //计算子进程需要拷贝的起点和大小
    int cpsize=len/n;
    int mod=len%n;
    //数据拷贝 ,memcpy
    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("munmao src err");
        exit(1);
    }
    //关闭文件
    close(srcfd);
    close(dstfd);
    return 0;
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux 中,可以使用多进程来实现文件拷贝。下面是一个简单的示例代码,展示了如何使用多进程进行文件拷贝: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #define BUF_SIZE 4096 void copy_file(const char* source, const char* destination) { int source_fd, dest_fd; ssize_t bytes_read, bytes_written; char buffer[BUF_SIZE]; // 打开源文件 source_fd = open(source, O_RDONLY); if (source_fd == -1) { perror("open"); exit(EXIT_FAILURE); } // 创建并打开目标文件 dest_fd = open(destination, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (dest_fd == -1) { perror("open"); exit(EXIT_FAILURE); } // 创建子进程 pid_t pid = fork(); if (pid == -1) { perror("fork"); exit(EXIT_FAILURE); } if (pid == 0) { // 子进程负责拷贝数据 while ((bytes_read = read(source_fd, buffer, BUF_SIZE)) > 0) { bytes_written = write(dest_fd, buffer, bytes_read); if (bytes_written != bytes_read) { perror("write"); exit(EXIT_FAILURE); } } if (bytes_read == -1) { perror("read"); exit(EXIT_FAILURE); } // 关闭文件描述符 close(source_fd); close(dest_fd); exit(EXIT_SUCCESS); } else { // 父进程等待子进程结束 wait(NULL); } } int main() { const char* source = "source.txt"; const char* destination = "destination.txt"; copy_file(source, destination); printf("文件拷贝完成!\n"); return 0; } ``` 在这个示例代码中,我们使用了`open()`函数打开源文件和目标文件,然后使用`fork()`创建了一个子进程。子进程负责从源文件中读取数据,并将数据写入目标文件中,而父进程则等待子进程结束。 需要注意的是,这只是一个简单的示例,可能有一些边界情况没有处理。如果需要在实际环境中使用,请根据实际需求进行适当的修改和完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值