利用无名管道实现简单并行计算
来源:互联网 发布:srs音效增强软件 编辑:程序博客网 时间:2024/05/20 11:22
名称:利用无名管道实现简单并行计算
说明:本程序利用无名管道进行进程间通信,达到多进程同时计算的目的。
基本算法是:首先在主进程里创建了一定数量的子进程,然后主进程通过无名管道向子进程传递要计算的数据,子进程计算后,通过无名管道将计算的结果(此处是求和)返回给主进程,主进程进行汇总。
#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <string.h>#include <malloc.h>#include <time.h> #define READ_END 0#define WRITE_END 1#define PRO_NUM 4 //进程数量#define DATA_NUM 100 //数据数量#define NUM (DATA_NUM / DATA_NUM) //每个进程所要处理的数据个数;//#define NUM (PRO_NUM)/(DATA_NUM) //运行结果有错误#define NUM 100 / 4typedef struct{ int main_to_sub_fd[2]; //信息流从主进程流向子进程,管道读写描述符(即主进程向子进程传递数据) int sub_to_main_fd[2]; //信息流从子进程流向主进程,管道读写描述符(即子进程将计算的结果返回给主进程) }FD_table;FD_table fdtable[PRO_NUM]; //创造模拟的随机数数据,此处的种子是进程序号void create_rand(int ** data,int ran){ int i = 0; *data = (int *)malloc(sizeof(int) * NUM); //申请数据空间 srand(ran); for(;i<NUM;++i) { (*data)[i] = rand() % 100 + 1; //产生100以内的随机数 }}//产生管道表,用于主进程查询用int create_pipe_table(){ int i = 0; for(;i<PRO_NUM;++i) { if(-1 == pipe(fdtable[i].main_to_sub_fd)) //创造管道 { printf("pipe failed.\n"); return 1; } if(-1 == pipe(fdtable[i].sub_to_main_fd)) //创造管道 { printf("pipe failed.\n"); return 1; } } return 0;}//每个子进程求和int cal(int data[]){ int i = 0; int sum = 0; for(;i<NUM;++i) { sum = sum + data[i]; } return sum;}//子进程的所有操作void child_pro(int data[],int flag){ int sum = 0; int i = 0; read((fdtable[flag]).main_to_sub_fd[READ_END],data,sizeof(int)*NUM); //子进程从主进程的管道中读取数据 sum = cal(data); //每个子进程计算求和 printf("(%d):the sum is %d\n",getpid(),sum); write(fdtable[flag].sub_to_main_fd[WRITE_END],&sum,sizeof(int)); //子进程计算结果写入到主进程}int main(){ int temp = 0; pid_t pid; int i = 0; int flag = 0; //用来识别进程的编号 int sums[PRO_NUM]; int total_sum = 0; int *_data = NULL; //用于主进程产生随机数,并传给子进程 memset(sums,0,sizeof(int)*PRO_NUM); int data[NUM]; //用于存储子进程从主进程接收到的数据 memset(data,0,sizeof(int)*NUM); create_pipe_table(fdtable); while(1) { //每次循环创建进程 pid = fork(); if(pid > 0 ) //父进程 { if( i >= PRO_NUM - 1 ) { for(i = 0;i<PRO_NUM;++i) { create_rand(&_data,i); write(fdtable[i].main_to_sub_fd[WRITE_END],_data,sizeof(int)*NUM); //向管道中写入随机数 } for(i = 0;i<PRO_NUM;++i) { read(fdtable[i].sub_to_main_fd[READ_END],&sums[i],sizeof(int)); //从子进程管道中读出数据 total_sum = total_sum + sums[i]; } printf("The total sum is %d\n",total_sum); //主进程结束,在此等待 while(1) { printf("the parent process is waiting ....\n"); sleep(3); }; } } else //子进程 { printf("this is the %d process.\n",i); flag = i; break; } ++i; } //子进程执行 child_pro(data,flag); return 0;}
总结:这个程序写了好久,一开始有个问题一直得不到解决。就是主进程接受到的结果老是不正确,总是其发送给子进程的第一个数据。而子进程接收到的数据,也是从主进程发送的第二个数据开始的。
折腾了好几天,终于弄清楚了。还是对于管道没理解清楚。每创建一个管道,就会产生两个描述符,只要得到了这两个描述符,就能从相应的管口进行读写。本程序原来对于每个程序只维护了一个管道,本来想的是,主进程向这个管道写入原始数据,子进程从这个管道中读入原始数据。子进程计算后,将结果在通过这个管道写入,然后主进程将结果读出。感觉是没什么问题,但是看程序就知道,主进程在向每个子进程写入数据后,就一直轮循向管道中读入数据,这个时候如果子进程还没将结果写入管道,那么主进程读入的结果就是错误的。(原来犯得错误就是主进程读的数据是自己原来写入的第一个数据)。我去,扯了这么多,突然想到可以用一句话代替啊,就是管道是半双工通信的。傻了我。
找到了错误原因,改起来就方便了,对每个子进程和主进程之间的通信又加了一对管道,即使用两组管道就可以了。
阅读全文
1 0
- 利用无名管道实现简单并行计算
- 利用有名管道&无名管道 实现 简单的多人聊天
- vc 利用无名管道 控制台程序实现cmd功能
- 利用IPython实现并行计算
- 一个简单的无名管道示例
- 1.5 简单的无名管道使用
- 无名管道
- 无名管道
- 无名管道
- 无名管道
- 无名管道
- 无名管道
- 无名管道
- 无名管道
- 无名管道
- 无名管道
- 无名管道
- 无名管道
- 【爱奇艺2018秋季校招前端工程师(第一场)】 试题回顾
- 数据类比赛的基本处理流程和方法
- mysql 慢查询及深入调优
- html5表单验证2
- expect命令使用
- 利用无名管道实现简单并行计算
- JavaScript-----JS---JavaScript的介绍
- C语言小项目-注释转换
- tcp/udp校验和以及伪首部介绍
- BP神经网络初步应用(数据预处理)基于matlab
- hive数据倾斜优化
- 网易2018秋招编程题
- C,C++ 的发展和标准化进程
- Web安全与防御视频教程分享