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; }
测试如图:
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- Linux学习之----进程
- Linux学习之----进程间通信
- Linux配置NAT模式(电脑连手机热点)
- Linux学习之----信号
- Linux学习之----终端和守护进程
- Linux学习之----线程
- Linux学习之----多线程复制文件练习
- Linux学习之----线程同步与进程同步
- Linux下配置本地git并同步github远程仓库
- Linux驱动中动态定时器的使用
- Linux yum日常操作
- 【Linux】Linux日常操作命令
- Linux查看程序被Killed原因
- Linux虚拟机(CentOS5)学习笔记(一)之基本命令
- Linux虚拟机(CentOS5)学习笔记(二)之基本命令
- Linux虚拟机(CentOS5)学习笔记(三)之Vim
- Linux虚拟机(CentOS5)学习笔记(四)之自有服务
- Linux虚拟机(CentOS5)学习笔记(五)之自有服务
- linux spark连接MySQL数据库并打印到控制台上
- 【华为云技术分享】Linux软件安装的几种方法 (一)—— apt-get