Linux多进程文件拷贝(C/C++)——方案二(使用mmap内存映射)

Linux多进程文件拷贝(C/C++)——方案二(使用mmap内存映射)

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

using namespace std;

int main(int argc,char* argv[])
{
        if(argc < 4) {
                cout << "Usage: ./a.out fileSrcPath fileDestPath processNumber" << endl;
                return 0;
        }
        int srcfd = open(argv[1],O_RDONLY);
        if(srcfd == -1) {
                perror("open src error");
                return -1;
        }
        int len = lseek(srcfd,0,SEEK_END);
        //cout << "src len = " << len << endl;
        if(len == -1) {
                perror("lseek src error");
                return -1;
        }
        char* ptr_r = (char*)mmap(NULL,len,PROT_READ,MAP_SHARED,srcfd,0);
        if(ptr_r == MAP_FAILED) {
                perror("mmap src error");
                return -1;
        }
        close(srcfd);
        int desfd = open(argv[2],O_RDWR|O_CREAT,0664);
        if(desfd == -1) {
                perror("open des error");
                return -1;
        }
        //也可以使用lseek,最后必须写点东西才行,否则会报Bus Error(总线错误)
        int ret = ftruncate(desfd,len);
        //cout << "des len = " << len << endl;
        if(ret == -1) {
                perror("ftruncate error");
                return -1;
        }
        char* ptr_w = (char*)mmap(NULL,len,PROT_WRITE,MAP_SHARED,desfd,0);
        close(desfd);
        if(ptr_w == MAP_FAILED) {
                perror("mmap des error");
                return -1;
        }
        int i; pid_t pid;
        //传进来的argv[3]参数是总进程数,所以创建argv[3]-1个子进程
        int childPronum = atoi(argv[3])-1;
        //将文件分为总进程数量个块
        int eachSize = len/(childPronum+1);
        for(i=0;i<childPronum;i++) {
                pid = fork();
                if(pid == -1) {
                        perror("fork error");
                        return -1;
                } else if(pid == 0) {
                        break;
                }
        }
        //子进程拷贝前childPronum 份等长数据
        while(pid == 0 && childPronum--) {
                if(i == childPronum) {
                        memcpy(ptr_w+i*eachSize,ptr_r+i*eachSize,eachSize);
                        cout << "child_" << i << "'s pid =  " << getpid() << ",writes bytes = " << eachSize << endl;
                        break;
                }
        }
        //父进程拷贝最后一份长度不确定数据
        if(pid > 0 && i == childPronum) {
                memcpy(ptr_w+i*eachSize,ptr_r+i*eachSize,len-i*eachSize);
                cout << "i = " << i << " parent's pid =  " << getpid() << ",writes bytes = " << len-i*eachSize << endl;
        }
        if(munmap(ptr_r,len) == -1 || munmap(ptr_w,len) == -1) {
                perror("munmap error");
                return -1;
        }
        return 0;
}
若有误请指出,谢谢
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值