并发任务的可视化

一、任务要求:

在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

#include

#include

#include

#include

#include

#include

#include

#include

#include

#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[]="多进程并发可视化

父进程
子进程A执行进度
子进程B执行进度
子进程A
子进程B
子进程C
";

sprintf(body,"多进程并发可视化

父进程
%s
%s
子进程A
子进程B
子进程C
%s
",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;

}

并发任务的可视化并发任务的可视化并发任务的可视化并发任务的可视化并发任务的可视化并发任务的可视化并发任务的可视化并发任务的可视化


文章题目:并发任务的可视化
路径分享:http://myzitong.com/article/pshjji.html