您的位置:首页 > 运维架构 > Linux

Linux学习之----多进程复制文件小练习

2020-04-07 12:31 1856 查看
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <math.h>
#include <iostream>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/wait.h>

using namespace std;

int string2Int(const char *s)
{
int ret = 0;

if (s != NULL)
{
unsigned int len = strlen(s);

for (int i = len - 1; i >= 0; i--)
{
int v = s[i] - '0';

if ((0 <= v) && (v <= 9))
{
ret += (pow(10, len - i - 1) * v);
}
else
{
return -1;
}
}
}

return ret;
}

//格式 ./程序名  要复制的文件  复制到哪个文件  要开启的进程数

int main(int argc, const char *argv[])
{
int ret = 0;

if (argc < 2)
{
dprintf(STDOUT_FILENO, "%s : Paramter count must be more than two ...", argv[0]);
exit(1);
}

int pro_count = string2Int(argv[3]);

if (pro_count == -1)
{
printf("%s : Process count must be more than 0 ...", argv[0]);
exit(1);
}

int fd_r = open(argv[1], O_RDWR | O_CREAT, 0644);
int fd_w = open(argv[2], O_RDWR | O_CREAT, 0644);

if ((fd_r == -1) || (fd_w == -1))
{
perror("open ");
exit(1);
}

int file_size = lseek(fd_r, 0, SEEK_END);
ret = ftruncate(fd_w,file_size);

if(ret == -1)
{
perror("ftruncate error ");
close(fd_r);
close(fd_w);
exit(1);
}

char *p = reinterpret_cast<char*>(mmap(NULL, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_r, 0));

if (p == MAP_FAILED)
{
perror("mmap error ");
close(fd_r);
close(fd_w);
exit(1);
}

ret = read(fd_r, p, file_size);

if (ret == -1)
{
perror("read error ");
close(fd_r);
close(fd_w);
ret = munmap(p, file_size);

if (ret == -1)
{
perror("munmap error ");
}

exit(1);
}

//单个进程读多少个字节,最后一个进程把剩下的读完
int single_read_count = static_cast<int>(1.0 * file_size / pro_count);
//从哪里开始读写
char* rw_pos = p;
//该进程负责读写多少字节
int rw_count = single_read_count;

int flag = 0;
for(flag = 0;flag < pro_count - 1;flag++)
{
ret = fork();

if(ret == 0)
{
//子进程
rw_pos = p + (flag + 1) * single_read_count;

if((flag + 1) == (pro_count - 1))
{
//是最后一个进程
rw_count = file_size - (single_read_count * (pro_count - 1));
}

flag++;

break;
}
else
{
//是父进程
if((flag + 1) == (pro_count - 1))
{
flag = 0;
break;
}
}
}

printf("flag = %d , rw_pos = %p , rw_count = %d \n",flag,rw_pos,rw_count);

lseek(fd_w,rw_pos - p,SEEK_SET);
write(fd_w,rw_pos,rw_count);

close(fd_r);
close(fd_w);

ret = munmap(p, file_size);

if (ret == -1)
{
perror("munmap error ");
exit(1);
}

//父进程,要回收子进程
if(flag == 0)
{
sleep(2);
int i = 0;
while(wait(NULL) != -1)
{
printf("父进程回收了一个子进程,i = %d\n",i++);
}
}

return ret;
}

测试如图:

  • 点赞
  • 收藏
  • 分享
  • 文章举报
苏瓜皮 发布了17 篇原创文章 · 获赞 1 · 访问量 1497 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: