- A+
所属分类:linux技术
一、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); }
一入编程深似海,多学多查多动手