并发任务的可视化
一、任务要求:
在linux系统中设计一个父进程,三个子进程(A,B,C)。子进程A,B同时被父进程启动来计算(不实现具体的计算任务,先用CPU空跑来代替)。进程A计算5分钟,而进程B计算8分钟。当进程A,B都计算完成后才能启动进程C,进程C计算3分钟。自己寻找前端的可视化方案,当进程在并发计算时,打开网页能够看到,那个进程当前正在计算,并且要可视化的显示计算的进度,还要看出各个进程之间的约束关系。
二、解答思路:
1.父进程fork出子进程A,B。A,B同时执行。进程A B内执行循环空跑CPU,利用gettimeofday()函数获取时间来控制执行时间。
2.定义全局变量标志进程A B状态,初始化为假,若A B执行完毕后,则子进程A B向主进程发送信号,主进程收到子进程A B完成的信号后调用相应函数改变表示A B状态的变量为真,当A B都完成后 ,主进程fork出子进程C,子进程的运行方法同进程A B。
3.可视化:利用浏览器进行可视化显示,则主进程为服务器,主进程通过管道与进程A B C进行通信,获取进程运行进度,通过浏览器发出请求,主进程收到请求后向浏览器发送进程运行情况。网页通过自动刷新不断更新数据。
三、代码:
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/time.h>
#define TRUE 0x01
#define FALSE 0x00
#define MAX 10
#define PORT 8080
char flagA=FALSE; //进程A完成标志
char flagB=FALSE; //进程B完成标志
int flagC=1; //进程C完成标志 1:未开始 2:已开始 3:已结束
int flagCount=0; //进程C建立标志
//进程A信号处理
void endofA(int sig)
{
if(sig==SIGUSR1)
{
flagA=TRUE;
printf("修改了A\n");
}
return;
}
//进程B信号处理
void endofB(int sig)
{
if(sig==SIGUSR2)
{
flagB=TRUE;
printf("修改了B\n");
}
return;
}
//进程C信号处理
void endofC(int sig)
{
if(sig==SIGINT)
{
flagB=3;
printf("修改了C\n");
}
return;
}
int main(int argc,char *argv[])
{
int fdA[2],n; //父进程与A进程通信管道
char stateA[50]="子进程A执行中";
char stateB[50]="子进程B执行中";
char stateC[50]="子进程B执行中";
char temp[5];
pipe(fdA);
int fdB[2]; //父进程与B进程通信管道
pipe(fdB);
int server_socket = socket(AF_INET, SOCK_STREAM, 0); //服务器socket
struct sockaddr_in server_addr; //服务器地址
memset(&server_addr, 0, sizeof(server_addr)); //清空服务器地址
server_addr.sin_family = AF_INET; //IPv4 网络协议的套接字类型
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(PORT);
bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr));
pid_t pidA;
if((pidA=fork())<0)
printf("forkA fail");
if(pidA==0) //进程A
{
close(fdA[0]);
int runtime;
struct timeval start,end;
n=gettimeofday(&start, NULL);
gettimeofday(&end, NULL);
//空跑300秒,每3秒向管道内写入已运行时间
//采用网页显示,主进程与A之间有480个像素,故速度为1.6
while((runtime=(end.tv_sec-start.tv_sec))<=300)
{
sleep(3);
char timeA[20]={0};
double distanceA=1.6*runtime;
sprintf(timeA,"%.2f",distanceA);
gettimeofday(&end, NULL);
write(fdA[1],timeA,sizeof(timeA));
}
//向父进程发送信号
if(kill(getppid(),SIGUSR1)==-1)
{
printf("process A send fail");
exit(0);
}
}
else
{
pid_t pidB;
pidB=fork();
//B进程
if(pidB==0)
{
close(fdB[0]);
int runtimeB=0;
float distanceB=0;
struct timeval startB,endB;
n=gettimeofday(&startB, NULL);
gettimeofday(&endB, NULL);
//空跑480秒,每3秒向管道内写入已运行时间
//采用网页显示,主进程与A之间有480个像素,故速度为1
while((runtimeB=(endB.tv_sec-startB.tv_sec))<=480)
{
sleep(3);
char timeB[20]={0};
distanceB=1*runtimeB;
sprintf(timeB,"%.2f",distanceB);
gettimeofday(&endB, NULL);
write(fdB[1],timeB,sizeof(timeB));
}
//向父进程发送信号
if(kill(getppid(),SIGUSR2)==-1)
{
printf("process B send fail");
exit(0);
}
}
else
{
close(fdA[1]);
close(fdB[1]);
signal(SIGUSR1,endofA);
signal(SIGUSR2,endofB);
signal(SIGINT,endofC);
while(1)
{
int fdC[2];
close(fdC[1]);
//判断A与B是否运行完毕
if(flagA==TRUE&&flagB==TRUE&&flagC!=3&&flagCount==0)
{
flagC=2;
pipe(fdC);
pid_t pidC;
pidC=fork();
flagCount=1;
//C进程
if(pidC==0)
{
close(fdC[0]);
int runtimeC=0;
struct timeval startC,endC;
n=gettimeofday(&startC, NULL);
gettimeofday(&endC, NULL);
float distanceC=0;
//空跑180秒,每3秒向管道内写入已运行时间
//采用网页显示,主进程与A之间有180个像素,故速度为1
while((runtimeC=(endC.tv_sec-startC.tv_sec))<=180)
{
sleep(3);
char timeC[20]={0};
distanceC=1*runtimeC;
sprintf(timeC,"%.2f",distanceC);
gettimeofday(&endC, NULL);
int n=write(fdC[1],timeC,sizeof(timeC));
printf("\n%dC写入管道\n",n);
}
//向父进程发送信号
if(kill(getppid(),SIGINT)==-1)
{
printf("process C send fail");
exit(0);
}
exit(0);
}
}
char readA[20];
char widthA[20]={0};
char widthB[20]={0};
char readC[20];
char widthC[20]={0};
if(!flagA)
{
read(fdA[0],readA,20);
strcpy(widthA,readA);
}
else{
strcpy(widthA,"480");
strcpy(stateA,"子进程A执行完毕");
}
char readB[20];
if(!flagB)
{
read(fdB[0],readB,20);
strcpy(widthB,readB);
}
else{
strcpy(widthB,"480");
strcpy(stateB,"子进程B执行完毕");
}
char stateC[50]={0};
if(flagC==1)
{
strcpy(widthC,"0");
strcpy(stateC," ");
}
else if(flagC==2)
{
read(fdC[0],readC,20);
strcpy(widthC,readC);
strcpy(stateC,"子进程C执行中");
}
else
{
strcpy(widthC,"180");
strcpy(stateC,"子进程C完毕");
}
listen(server_socket, 5);
int client_socket = accept(server_socket, NULL, NULL);
char buf[1024];
read(client_socket, buf, 1024);
char status[] = "HTTP/1.0 200 OK\r\n";
Char header[]="Server:DWBServer\r\nContent-Type: text/html;charset=utf-8\r\n\r\n";
char body[]="<html><head><meta http-equiv='refresh' content='3'><title>多进程并发可视化</title></head><body><div style='height:250px;width:50px;background-color: red;'>父进程</div><div style='height:8px;width:0px;background-color: #00ff2f;position: absolute;left: 60px;top: 50px;'>子进程A执行进度</div><div style='height:8px;width:0px;background-color: #00ff2f;position: absolute;left: 60px;top: 200px;'>子进程B执行进度</div><div style='height:100px;width:50px;background-color: #00ff2f;position: absolute;left: 530px;top: 0px;'>子进程A</div><div style='height:100px;width:50px;background-color: #000dff;position: absolute;left: 530px;top: 150px;'>子进程B</div><div style='height:50px;width:8px;background-color: #0b000c;position: absolute;left: 550px;top: 100px;'></div><div style='height:100px;width:50px;background-color: #f113ff;position: absolute;left: 738px;top: 80px;'>子进程C</div><div style='height:8px;width:0px;background-color: #f113ff;position: absolute;left: 558px;top: 120px;'></div></body></html>";
sprintf(body,"<html><head><meta http-equiv='refresh' content='3'><title>多进程并发可视化</title></head><body><div style='height:250px;width:50px;background-color: red;'>父进程</div><div style='height:8px;width:%spx;background-color: #00ff2f;position: absolute;left: 60px;top: 50px;'>%s</div><div style='height:8px;width:%spx;background-color: #00ff2f;position: absolute;left: 60px;top: 200px;'>%s</div><div style='height:100px;width:50px;background-color: #00ff2f;position: absolute;left: 530px;top: 0px;'>子进程A</div><div style='height:100px;width:50px;background-color: #000dff;position: absolute;left: 530px;top: 150px;'>子进程B</div><div style='height:50px;width:8px;background-color: #0b000c;position: absolute;left: 550px;top: 100px;'></div><div style='height:100px;width:50px;background-color: #f113ff;position: absolute;left: 738px;top: 80px;'>子进程C</div><div style='height:8px;width:%spx;background-color: #f113ff;position: absolute;left: 558px;top: 120px;'>%s</div></body></html>",widthA,stateA,widthB,stateB,widthC,stateC);
write(client_socket, status, sizeof(status));
write(client_socket, header, sizeof(header));
write(client_socket, body, sizeof(body));
close(client_socket);
}
}
}
close(server_socket);
return 0;
}
转载于:https://blog.51cto.com/13958494/2171422
相关文章:
银监会警示担保圈贷款风险 联保贷款变异 防多米诺效应
互保联保本是解决小微企业以及农村金融贷款需求的重要创新,但却在部分行业、部分地区逐渐变异,成为引发风险事件的诱因。 据媒体报道,银监会近日发文要求加强企业担保圈贷款风险的防范和化解工作。银监会警示,担保圈企业风险较高的…

SharePoint 2007 系列(4) -Site Settings
Site administration 转载于:https://www.cnblogs.com/xuxiaoguang/archive/2008/11/05/1326913.html

软件项目管理重点总结
文章目录概论走进项目管理把控环境,控制过程整合项目资源控制项目范围保障项目进度驾驭项目成本保证项目质量协调项目人力资源改善项目的沟通应对项目风险关注项目的采购和外包概论 项目的定义:为创造一个特定的产品、服务或者成果而采取的临时性的努力…

jQuery发送含有数组参数的ajax请求以及后台Struts2的OGNL解析错误
当使用jquery1.3以上版本时,进行ajax参数传值时,会出现以下的一个错误: ognl.ExpressionSyntaxException: Malformed OGNL expression: f[] [ognl.ParseException: Encountered " "]" "] "" at line 1, column 3. 这个错…

数据绑定以及Container.DataItem绑定技巧
数据绑定以及Container.DataItem绑定技巧 灵活的运用数据绑定操作绑定到简单属性:<%#UserName%>绑定到集合:<asp:ListBox id"ListBox1" datasource<%# myArray%> runat"server">绑定到表达式:<%#(class1.property1.ToString() "…

LeetCode 76. Minimum Window Substring / 567. Permutation in String
76. Minimum Window Substring 典型Sliding Window的问题,维护一个区间,当区间满足要求则进行比较选择较小的字串,重新修改start位置。 思路虽然不难,但是如何判断当前区间是否包含所有t中的字符是一个难点(t中字符有重…

计算机网络中的协议数据单元的控制信息主要包括哪些内容
在计算机网络的数据传输过程中会对数据进行封装,俗称加头(链路层还会加尾),增加的控制信息主要包括以下内容: 地址(Address):用来标识发送端或接收端差错检测编码(Error-detecting code):用于差错检测或纠正协议控制(…

jQuery 超屏加载
jQuery 超屏加载,当文档超出屏幕的高度时,加载最新下个列数据 $(window).scroll(function () {var height $(document).height(); //页面的高度var keheight $(window).height(); //浏览器可视的高度var sheight $(document).scrollTop(); //滚动的高…

自己动手,打造轻量级VSCode/C#环境代替LinqPad
.Net 的项目都挺重的,一直想找一个轻量级的 CSharp 环境,能像Python那样,选一个文件就能跑的。之前用的是 LinqPad,但它的缺点也很明显: (1) 不付费,自动完成不能用(…

让html:error只显示第一条错误信息
struts-config.xml 中的 <plug-in className"org.apache.struts.validator.ValidatorPlugIn"> 里面加上 <set-property property"stopOnFirstError" value"true"/> 就可以了 </plug-in> 转载于:https://www.cnblogs.com/kakak…

(C++)除基取余法:将十进制数转化为Q进制数
所谓基,就是指将要转换成的进制Q。 除基取余的意思就是:每次将待转换数除以Q,然后将得到的余数作为低位存储,而商则继续除以Q并重复上面的操作,直至商0时,将所有位从高到低输出就可以得到Q进制数。 代码实…

《C++ Primer 4th》读书笔记 第5章-表达式
原创文章,转载请注明出处: http://www.cnblogs.com/DayByDay/p/3912114.html 转载于:https://www.cnblogs.com/DayByDay/p/3912114.html

vue - check-versions.js for child_process
webpack之类的配置文件. webpack.base.conf.js

EasyPHP-2.0b1+ Mantis-1.1.0安装及技巧
转载: EasyPHP-2.0b1 Mantis-1.1.0安装及技巧 注:部分配置来源网络,写此文仅为以后配置提供参考 Mantis是一个轻量级的brower的bug管理系统,界面直观,简单易用,安装简单,支持多语言,…

PAT 显示格式错误
记录一: 2021/7/8 10:26 代码逻辑写错了,一个该没有空格的地方也加了空格

翡润年华-毛货展示003
www.520jade.com转载于:https://www.cnblogs.com/520jade/p/3912790.html

json学习之路
总感觉自己比别人慢好几排,不知道到底多少,但至少一排吧??? 一直很喜欢js,但刚开始编程的时候一直把js停留在"有效性验证"上,大大浪费了js.不过当时已经知道js很强大了,可…

layoutSubviews 调用情况
init初始化不会触发layoutSubviews 但是是用initWithFrame 进行初始化时,当rect的值不为CGRectZero时,也会触发addSubview会触发layoutSubviews设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化滚动一个UIScrollView会触发la…

python基本数据类型之序列类型和映射类型
序列类型:字符串/元组/列表 映射类型:字典 更正::三引号也可以用来表示字符串,并且有额外用途:①搞定多行字符串 ②内用单引号和双引号 列表可以根据内容得到索引 有多个相同内容时根据第一个得到下标

关于EF中ApplyCurrentValues和ApplyOriginalValues区别
关于EF中ApplyCurrentValues和ApplyOriginalValues区别:两者都是编辑数据时使用。 // // 摘要: // 将 System.Data.Objects.ObjectStateEntry 的 System.Data.Objects.ObjectStateEntry.CurrentValues // 属性设置为与所提供对象的属性…

PHP Session中保存Object
在PHP中,使用Session保存Object时,PHP会将Object自动序列化。在读取Session变量时,准确地说是在session_start时,PHP会将Session中已序列化的Object反序列化。这时就需要Class的定义,Why?因为序列化时只是保…

kali linux网络配置
事情是这样的 今天早上想安装一个按个人信息生成密码的软件 发现无法安装 发现问题后 我首先检查了kali有没有获取到IP 然后就是没有获取IP 怎么解决问题如下: 原理进程: 1.写入dhcp服务 1.进行DNS设置 首先输入命令: gedit /etc/network/int…

流程快速开发平台,工作流引擎中间件,工作质量考核设计
为什么80%的码农都做不了架构师?>>> 工作质量考核设计关键字:CCBPM工作质量考核时效考核 需求背景:我们把在工作流程引擎中的考核分为两种模式,一种是时效考核、另外一种是质量考核。 时效考核就是对用户的操作进行时间点的记录&…

Windows 7 操作系统核心文件
【Windows\Boot】启动必须文件 【Windows\Help】帮助文件 【Windows\inf】安装硬件和软件时所需的inf文件 【Windows\System32】系统的主要组件 ActiveX文件(*.ocx)应用程序应用程序扩展(*.dll)控制面板项(*.cpl&#…

安装SQL SERVER2000提示注册表文件被挂起的解决方案
在安装SQL SERVER 2000时出现如下的提示: “以前的某个程序安装已在安装计算机上创建挂起的文件操作。运行安装程序之前必须重新启动计算机。” 按照提示重启计算机,再安装,仍然出现同样的提示。这是因为安装程序在先前的安装过程中在系统注册…

(C++)1046 Shortest Distance
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std;int friendDis[100010] {0};//邻居节点间的距离 int withStDis[100010] {0};//和第一个结点的距离 --本题的题眼,空间换时间的典例int ma…

Lesson 59-60 Househusband
1 particular 特别的,挑剔的adj eg. Ted was very particular about the color he used.特德在用色上非常讲究 2 freelance 自由作家n 自由的adj 当自由职业者vi eg. Michael Cross is a freelance journalist.迈克尔克罗斯是一名自由新闻记者。 eg. She has freela…

META Header
response.setHeader 是用来设置返回页面的头 meta 信息, 使用时 response.setHeader( name, contect ); meta是用来在HTML文档中模拟HTTP协议的响应头报文。meta 标签用于网页的<head>与</head>中 1、<meta name"Generator" contect"">用…

ubuntu安装deepin terminal 终端
1. 依赖库 sudo apt-get install libatk1.0-0 libc6 libcairo-gobject2 libcairo2 libfontconfig1 libfreetype6 libgdk-pixbuf2.0-0 libgee-0.8-2 libglib2.0-0 libgnutls30 libgtk-3-0 libjson-glib-1.0-0 libpango-1.0-0 libpangocairo-1.0-0 libsecret-1-0 libvte-2.91-0…