linux多进程—使用mmap映射实现文件拷贝

  • A+
所属分类:linux技术
摘要

一、mmap共享映射区 一入编程深似海,多学多查多动手   

一、mmap共享映射区

1、创建映射区函数mmap
void *mmap(void *addr,size_t length,int prot,int flags,int fd,off_t offset);
addr  传NULL
length  传映射区长度
prot 
PROT_READ 可读
PROT_WRITE  可写
flags
MAP_SHARED 共享的;对内存的修改会影响到源文件(源文件即fd对应的文件)
MAP_PRIVATE 私有的;对内存的修改不会影响源文件
fd 文件描述符,open打开一个文件
offset  偏移量
返回值:
成功返回 可用的内存首地址  
失败返回 MAP_FAILED
 
2、释放映射区munmap
int munmap(void *addr,size_t lenth); 
addr  传mmap的返回值
length 传出映射区长度
 
二、使用mmap映射---多进程拷贝代码
#include<stdio.h> #include<sys/mman.h> #include<unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include<string.h> #include <sys/wait.h>  int main(int argc,char* argv[]) {     if(argc!=3){         printf("please input correct parametersn");         return -1;      }        //1、打开文件src,dest     int fd_src=open(argv[1],O_RDONLY);     int fd_dest=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0664);      //2、使用fstat获取文件src的大小,truncate拓展文件dest的大小     struct stat buf;     fstat(fd_src,&buf);     int src_size=buf.st_size;     truncate(argv[2],src_size);     //3、mmap创建文件src,dest的映射,判断映射返回值,关闭文件描述符     char* mmap_src=mmap(NULL,src_size,PROT_READ,MAP_PRIVATE,fd_src,0);     char* mmap_dest=mmap(NULL,src_size,PROT_WRITE,MAP_SHARED,fd_dest,0);     if(mmap_src==MAP_FAILED||mmap_dest==MAP_FAILED){         perror("mmap err");         return -1;     }     close(fd_src);     close(fd_dest);     //4、对文件src的大小分段,fork创建子进程,编写自定义拷贝函数     int n=5;//进程数,开辟n个进程     int paragraph_size=src_size/(n-1);     int rear_paragraph_size=src_size%(n-1);      int i;     for(i=1;i<n;++i){         pid_t pid=fork();         if(pid==0){             break;         }     }     void mmap_copy(char* src,char* dest,int par_sleek,int size);     //5、父进程中拷贝最后一段,子进程中拷贝其他段,在父进程中关闭子进程,关闭mmap映射     if(i<n){//子进程         int paragraph_sleek=(i-1)*paragraph_size;//计算偏移量         mmap_copy(mmap_src,mmap_dest,paragraph_sleek,paragraph_size);     }     if(i==n){//父进程         int paragraph_sleek=(i-1)*paragraph_size;//计算偏移量         mmap_copy(mmap_src,mmap_dest,paragraph_sleek,rear_paragraph_size);         while(1)//回收子进程         {             pid_t wpid=waitpid(-1,NULL,WNOHANG);             if(wpid==-1){                 break;             }else if(wpid>0){                 printf("waitpid wpid=%dn",wpid);             }         }         munmap(mmap_src,src_size);         munmap(mmap_dest,src_size);     }     return 0; } void mmap_copy(char* src,char* dest,int par_sleek,int size) {     memcpy(dest+par_sleek,src+par_sleek,size); }

 

一入编程深似海,多学多查多动手