#include<sys/mman.h>
#include<fcntl.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<string.h>
#define MAX_LEN 10485760 //10M 大于10M默认每个进程映射10M 修改应为4096的倍数
#define N 10 //进程拷贝 低于10M,选择此方式,默认开十个进程,可修改
int plen,pnum;
void sys_err(char *str)
{
perror(str);
exit(1);
}
int comFile(char *Fname)
{
int fd;
if(access(Fname, F_OK))
fd = open(Fname, O_CREAT|O_WRONLY,0664);
else
fd = open(Fname, O_RDONLY);
return fd;
}
int process_cp(int i, char *sfile, char *dfile)
{
char buf[1024] = {0};
int count;
int sd = open(sfile, O_RDONLY);
int dd = open(dfile, O_WRONLY);
if(sd < 0 || dd < 0)
sys_err("mmap_cp fileOpen");
lseek(sd, i*plen, SEEK_SET);
lseek(dd, i*plen, SEEK_SET);
if(i != N-1 )
{
while(plen > 0)
{
count = plen > 1024? 1024:plen;
if(read(sd, buf, count) < 0)
sys_err("process_read");
write(dd, buf, count);
plen -= count;
}
}
else
{
while((count = read(sd, buf, 1024)) > 0 )
write(dd,buf,count);
}
return 0;
}
void mmap_cp(int i, char *sfile, char *dfile, int flen)
{
char *sm, *dm;
int len;
int sd = open(sfile, O_RDONLY);
int dd = open(dfile, O_RDWR);
if(sd < 0 || dd < 0)
sys_err("mmap_cp fileOpen");
len = (i == pnum-1 ? flen -i*plen:plen); //若为最后一个进程,拷贝长度为剩下所有
sm = mmap(NULL,len, PROT_READ, MAP_SHARED, sd, i*plen);
dm = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, dd, i*plen);
if(sm == MAP_FAILED || dm == MAP_FAILED)
sys_err("mmap");
memcpy(dm, sm, len);
munmap(sm, len);
munmap(dm, len);
}
int main(int argc, char *argv[])
{
int flen, flag, i = 0, sd, dd;
pid_t pid;
if(argc != 3)
sys_err("./ccp sourceFile DestFile..");
/**文件初步处理***/
sd = comFile(argv[1]);
dd = comFile(argv[2]);
if(sd < 0 || dd < 0)
sys_err("open source/dest");
if((flen =lseek(sd, 0, SEEK_END)) < 0)
sys_err("get seek ");
ftruncate(dd, flen);
pnum = ((flag = (flen > MAX_LEN ? 1:0)) > 0 ? flen/MAX_LEN+1 : N);
//根据文件大小选择何种cp方式
plen = (flag == 0 ? flen/(pnum-1):MAX_LEN);
//确定每个进程拷贝的长度
while(i < pnum)
{
pid = fork();
if(pid == 0)
break;
i++;
}
if(pid == 0) //子进程拷贝
{
close(sd);
close(dd);
if(flag)
mmap_cp(i,argv[1],argv[2],flen);
else
process_cp(i,argv[1],argv[2]);
}
else if(pid > 0)
wait(NULL);
else
sys_err("fork");
return 0;
}
多进程和mmap 实现copy的demo
最新推荐文章于 2022-12-23 17:05:25 发布
该博客介绍了一种使用多进程和内存映射(mmap)来复制文件的方法。通过创建多个进程,每个进程负责复制文件的一部分,或者利用mmap直接映射文件到内存进行复制。代码示例展示了如何根据文件大小选择合适的复制策略。
摘要由CSDN通过智能技术生成