Linux——实现文件的多进程拷贝
程序员文章站
2024-03-19 18:57:46
...
需求:实现文件多进程拷贝
假设有一个超大文件,需对其完成拷贝工作。为提高效率,可采用多进程并行拷贝的方法来实现。假设文件大小为len,共有n个进程对该文件进行拷贝。那每个进程拷贝的字节数应为len/n。但未必一定能整除,我们可以选择让最后一个进程负责剩余部分拷贝工作。可使用len % (len/n)将剩余部分大小求出。
为降低实现复杂度,可选用mmap来实现源、目标文件的映射,通过指针操作内存地址,设置每个进程拷贝的起始、结束位置。借助MAP_SHARED选项将内存中所做的修改反映到物理磁盘上。
实现源代码如下:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/wait.h>
void err_int(int ret, const char *err)
{
if (ret == -1) {
perror(err);
exit(1);
}
return ;
}
void err_str(char *ret, const char *err)
{
if (ret == MAP_FAILED) {
perror(err);
exit(1);
}
}
int main(int argc, char *argv[])
{
int fd_src, fd_dst, ret, len, i, n;
char *mp_src, *mp_dst, *tmp_srcp, *tmp_dstp;
pid_t pid;
struct stat sbuf;
if (argc < 3 || argc > 4) {
printf("Enter like this please: ./a.out file_src file_dst [process number]\n");
exit(1);
} else if (argc == 3) {
n = 5; //用户未指定,默认创建5个子进程
} else if (argc == 4) {
n = atoi(argv[3]);
}
//打开源文件
fd_src = open(argv[1], O_RDONLY);
err_int(fd_src, "open dict.txt err");
//打开目的文件, 不存在则创建
fd_dst = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0664);
err_int(fd_dst, "open dict.cp err");
//获取文件大小
ret = fstat(fd_src, &sbuf);
err_int(ret, "fstat err");
len = sbuf.st_size;
if (len < n) //文件长度小于进程个数
n = len;
//根据文件大小拓展目标文件
ret = ftruncate(fd_dst, len);
err_int(ret, "truncate fd_dst err");
//为源文件创建映射
mp_src = (char *)mmap(NULL, len, PROT_READ, MAP_SHARED, fd_src, 0);
err_str(mp_src, "mmap src err");
//为目标文件创建映射
mp_dst = (char *)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd_dst, 0);
err_str(mp_dst, "mmap dst err");
tmp_dstp = mp_dst;
tmp_srcp = mp_src;
//求出每个子进程该拷贝的字节数
int bs = len / n; //每个子进程应该拷贝的字节数
int mod = len % bs; //求出均分后余下的字节数,让最后一个子进程处理
//创建N个子进程
for (i = 0; i < n; i++) {
if ((pid = fork()) == 0) {
break;
}
}
if (n == i) { //父进程
for (i = 0; i < n; i++)
wait(NULL);
} else if (i == (n-1)){ //最后一个子进程,它多处理均分后剩余几个字节
memcpy(tmp_dstp+i*bs, tmp_srcp+i*bs, bs+mod);
} else if (i == 0) { //第一个子进程
memcpy(tmp_dstp, tmp_srcp, bs);
} else { //其他子进程
memcpy(tmp_dstp+i*bs, tmp_srcp+i*bs, bs);
}
munmap(mp_src, len);
munmap(mp_dst, len);
return 0;
}
上一篇: 如何用Excel做M中选出N的抽奖
下一篇: (9)学习tp5之模型
推荐阅读
-
Linux——实现文件的多进程拷贝
-
java实现linux中gzip压缩解压缩算法:byte[]字节数组,文件,字符串,数据流的压缩解压缩
-
Java实现多文件的zip压缩和解压缩
-
在Linux中实现文本文件的复制_莫韵乐的小脚印笔记
-
Android 实现拷贝单个或多个文件和文件夹到另一个目录下,获取单个文件夹里面文件大小和单个文件夹下多个文件夹和文件的大小
-
GDB调试实践二(gdb找不到动态库,对运行中的进程生成core文件) 博客分类: Linux调试Linux开发 GDB
-
使用pscp实现windows与linux服务器之间文件拷贝 博客分类: Linux linuxwindowspscp
-
CI框架实现优化文件上传及多文件上传的方法
-
struts2实现多文件上传的示例代码
-
asp.net html控件的File控件实现多文件上传实例分享