linux系统编程-mmap实例:多进程拷贝文件
题目
-
有一个超大文件,需要对其进行拷贝,为了提高效率,可以采用多进程并行拷贝的方法。采用mmap来实现。
代码:当前文件下有大文件:myfile ,拷贝到当前 write(进程新建的)
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
pid_t pid;
int i=0;
int fd,fd1;
char*p;
struct stat buf;
int filesize=0;
int each_size=0;
int last_size=0;
fd=open("./myfile",O_RDWR); //打卡需要复制的大文件
if(fd ==-1)
{
perror("open_r error");
exit(1);
}
int tmp=fstat(fd,&buf); //获取大文件的信息
{
if( tmp==-1)
{ perror("fstat error");
exit(1);
}
}
fd1=open("./write",O_RDWR|O_CREAT,0644); //创建write文件,由它创建映射区
if(fd1 ==-1)
{
perror("open_w error");
exit(1);
}
int ret=ftruncate(fd1,buf.st_size); //将其拓展成和需要复制的文件 同样大小
if(ret ==-1)
{
perror("ftruncate error");
exit(1);
}
filesize = buf.st_size; //获取大文件的大小
each_size=filesize/5; //计算出每个进程 需要复制的字节数
last_size=filesize%5; // 绝大多数不是整数,所以最后一个文件需要多复制一点
p = mmap(NULL,filesize,PROT_READ|PROT_WRITE,MAP_SHARED,fd1,0); //对write文件进行映射
if(p==MAP_FAILED)
{
perror("mmap error");
exit(1);
}
for(i=0;i<5;i++) //循环创建5个子进程
{
pid=fork();
if(pid < 0)
{
perror("fork error");
exit(1);
}
else if(pid==0)
{
break;
}
}
if(i<5) //子进程
{
if(i<4) //前4个进程,每个读写 相同的 字节数
{
int c=read(fd,p+i*each_size,each_size);
if(c!=each_size)
{
printf("process %d read error",i);
}
}
else //最后一个进程 需要多读一点
{
int d=read(fd,p+i*each_size,each_size+last_size);
if(d!=each_size+last_size)
{
printf("last read erro");
}
}
}
else //父进程
{
while(wait(NULL)>0); //回收子进程
printf("all process finished\n");
close(fd);
close(fd1);
munmap(p,filesize); //回收映射区
}
printf("process %d id died\n",i);
return 0;
}
结果:在当前目录下,会有和myfile内容一样的write文件