文件多进程拷贝(针对Linux编程)

    科技2022-07-15  126

    本程序需要用到mmap函数在Linux内核创建映射区

    参数说明:

          参数1 addr:建立映射区的地址  NULL值,linux系统自动分配

         参数2 length:创建映射区大小(不能为0)

         参数3 port:映射区的权限 PORT_READ(读),PORT_WRITE(写),PORT_READ|PORT_WRITE

         参数4 flags:标志参数(常用于设定更新物理区域,设置共享,创建匿名映射区)

                         MAP_SHARED:会将映射区所做的操作反应到设备上

                         MAP_PRIVATEF:映射区所做的修改不会反应到物理设备上

        参数5 fd:用来创建映射区的文件描述符

        参数6 offset:映射文件的偏移量(4k的整数倍)

     

    返回值:

                  成功:返回创建映射区的首地址

                  失败:MAP_FALID宏

    使用mmap函数的注意事项:

    文件必须要有实际的大小(可以是空洞),不能只是一个创建的文件当MAP_SHARED时,创建映射区的权限小于等于文件的打开权限,并且每次创建映射区都隐含着一次对文件的读操作 ;当MAP_PRIVATE则无所谓,因为只对mmap中的权限是对内存的限制Offset文件偏移量必须是4K的整数倍参数length不能为0 文件描述符(fd)先关闭无影响Munmap传入的参数一定是mmap的返回地址,杜绝指针++操作Mmap映射区出错率非常高,一定要检查返回值

     

    文件多进程拷贝:

    #include<string.h> #include<sys/wait.h> #include<stdio.h> #include<stdlib.h> #include<sys/stat.h> #include<sys/types.h> #include<unistd.h> #include<fcntl.h> #include<sys/mman.h> int ProcessNum=5; //拷贝进程数 void ProcessStartCopy(const char *p_r, char *p_w,const int length){ //拷贝所需变量 int maxCopySize=length/ProcessNum; //最大拷贝字节数 int leave=length%maxCopySize; //剩余个数 const char *temp_r=p_r; char *temp_w=p_w; pid_t pid; //进程编号 int i; for( i=0;i<ProcessNum;i++){ pid=fork(); //创建子进程 if(pid==-1){ perror("fork error!"); exit(0); }else if(pid>0){ break; } } if(i==ProcessNum) { //父进程 for(int j=0;j<ProcessNum;j++) wait(NULL); //回收子进程 printf("拷贝完成!\n"); } else if(i>=0){ if(i==(ProcessNum-1)){ //最后一个进程,处理剩余部分数据 memcpy(temp_w+i*maxCopySize,temp_r+i*maxCopySize,maxCopySize+leave); }else if(i==0) { memcpy(temp_w,temp_r,maxCopySize); } else{ memcpy(temp_w+i*maxCopySize,temp_r+i*maxCopySize,maxCopySize); } } } //获得文件的大小 int getFileLength(int fd){ struct stat st; fstat(fd,&st); return st.st_size; } //拷贝文件函数 void FileCpy(const char *root,const char * target){ int fd_w,fd_r; //文件描述符存储变量 char *p_r=NULL; //映射空间指针 int length; //文件长度 char *p_w=NULL; //打开要读文件 fd_r=open(root,O_RDWR); if(fd_r==-1){ perror("文件打开失败!"); exit(1); } //求文件长度 length=getFileLength(fd_r); //打开要写文件 fd_w=open(target,O_TRUNC|O_RDWR); //文件以O_TRUNC方式打开,会使文件为空致使p_w 映射区出错 if(fd_w==-1){ //文件不存在或者文件出错 fd_w=open(target,O_CREAT|O_RDWR,0644); if(fd_w==-1){ perror("写文件操作出错!"); exit(1); } } ftruncate(fd_w,length); //拓展文件防止mmap操作出错 //创建映射区 p_r=(char*)mmap(NULL,length,PROT_READ|PROT_WRITE,MAP_SHARED,fd_r,0); p_w=(char*)mmap(NULL,length,PROT_READ|PROT_WRITE,MAP_SHARED,fd_w,0); if(p_r==MAP_FAILED||p_w==MAP_FAILED){ perror("mmap error!"); exit(1); } //关闭文件 close(fd_r); close(fd_w); //开始拷贝 ProcessStartCopy(p_r,p_w,length); //释放映射区 munmap(p_r,length); munmap(p_w,length); } int main(int argc,char *argv[]){ if(argc!=3){ printf("缺少传入参数或者传入参数过多!\n"); exit(1); } FileCpy(argv[1],argv[2]); sleep(20); return 0; }

     

     

     

    Processed: 0.013, SQL: 8