#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;
}
Linux学习之----多进程复制文件小练习
最新推荐文章于 2022-11-03 11:01:17 发布