这里利用mmap函数创建内存映射区的方式来实现多个进程对文件进行拷贝的功能。其中利用到的函数主要有access、lseek、open、ftruncate、mmap、munmap、fork。
其中主要步骤如下:
①利用access判断要复制的文件是否存在,如果存在就用open函数打开,不存在的话就返回错误。
②利用lseek函数获取要复制文件的大小,其中利用了SEEK_END宏,意思是知道文件尾。
③利用mmap把该文件映射到内存中,返回指针用于操作多进程拷贝。
至此就获得了要读文件的所有需要的信息了,下面只要把该文件指针指向内容写到新文件就可以了。
④用open函数的O_RDWR|O_CREAT宏指定打开(没有改文件就创建新文件)。
⑤用ftruncate函数拓展上面返回的文件描述符指向文件的大小。
⑥同样用mmap创建新文件的内存映射区,返回指向该映射区的指针。
⑦利用fork函数创建多个进程,并用for循环中的i判断是哪个子进程。
⑧对每个子进程利用memcpy对指针指向的内存进行复制即可。
代码如下:
#include<stdio.h>
#include<unistd.h>
#include<sys/mman.h>
#include<fcntl.h>
#include<string.h>
int main(){
int o_fd,f_fd,c_fd,len,ret,i;
//read file
if(!access("master_bitcoin.pdf",F_OK)){
o_fd=open("master_bitcoin.pdf",O_RDWR);
if(o_fd==-1){
perror("open o_fd error");
}
}
len=lseek(o_fd,0,SEEK_END);
void *ptr_r=mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,o_fd,0);
if(ptr_r==MAP_FAILED){
perror("mmap ptr_r error");
}
//write file
c_fd=open("copy.pdf",O_RDWR|O_CREAT,0777);
if(c_fd==-1){
perror("open o_fd error");
}
ret=ftruncate(c_fd,len);
if(ret==-1){
perror("ftruncate error");
}
void *ptr_w=mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,c_fd,0);
if(ptr_w==MAP_FAILED){
perror("mmap ptr_w error");
}
//multi-process copy
for(i=0;i<4;i++){
f_fd=fork();
if(f_fd==0){//son
break;
}
else if(f_fd==-1){
perror("fork error");
}
else{
continue;
}
}
if(i==4){//parent process
memcpy(ptr_w+4*len/5,ptr_r+4*len/5,len-4*len/5);
printf("parent copy 5st distinct,over!\n");
}
if(i==0){//1st son
memcpy(ptr_w,ptr_r,len/5);
printf("son_1 copy 1st distinct,over!\n");
}
if(i==1){//2st son
memcpy(ptr_w+len/5,ptr_r+len/5,len/5);
printf("son_2 copy 2st distinct,over!\n");
}
if(i==2){//3st son
memcpy(ptr_w+2*len/5,ptr_r+2*len/5,len/5);
printf("son_3 copy 3st distinct,over!\n");
}
if(i==3){//4st son
memcpy(ptr_w+3*len/5,ptr_r+3*len/5,len/5);
printf("son_4 copy 4st distinct,over!\n");
}
close(o_fd);
close(c_fd);
munmap(ptr_r,len);
munmap(ptr_w,len);
}