您好,登錄后才能下訂單哦!
在linux系統(tǒng)中設(shè)計(jì)一個(gè)父進(jìn)程,三個(gè)子進(jìn)程(A,B,C)。子進(jìn)程A,B同時(shí)被父進(jìn)程啟動(dòng)來(lái)計(jì)算(不實(shí)現(xiàn)具體的計(jì)算任務(wù),先用CPU空跑來(lái)代替)。進(jìn)程A計(jì)算5分鐘,而進(jìn)程B計(jì)算8分鐘。當(dāng)進(jìn)程A,B都計(jì)算完成后才能啟動(dòng)進(jìn)程C,進(jìn)程C計(jì)算3分鐘。自己尋找前端的可視化方案,當(dāng)進(jìn)程在并發(fā)計(jì)算時(shí),打開網(wǎng)頁(yè)能夠看到,那個(gè)進(jìn)程當(dāng)前正在計(jì)算,并且要可視化的顯示計(jì)算的進(jìn)度,還要看出各個(gè)進(jìn)程之間的約束關(guān)系。
1.父進(jìn)程fork出子進(jìn)程A,B。A,B同時(shí)執(zhí)行。進(jìn)程A B內(nèi)執(zhí)行循環(huán)空跑CPU,利用gettimeofday()函數(shù)獲取時(shí)間來(lái)控制執(zhí)行時(shí)間。
2.定義全局變量標(biāo)志進(jìn)程A B狀態(tài),初始化為假,若A B執(zhí)行完畢后,則子進(jìn)程A B向主進(jìn)程發(fā)送信號(hào),主進(jìn)程收到子進(jìn)程A B完成的信號(hào)后調(diào)用相應(yīng)函數(shù)改變表示A B狀態(tài)的變量為真,當(dāng)A B都完成后 ,主進(jìn)程fork出子進(jìn)程C,子進(jìn)程的運(yùn)行方法同進(jìn)程A B。
3.可視化:利用瀏覽器進(jìn)行可視化顯示,則主進(jìn)程為服務(wù)器,主進(jìn)程通過(guò)管道與進(jìn)程A B C進(jìn)行通信,獲取進(jìn)程運(yùn)行進(jìn)度,通過(guò)瀏覽器發(fā)出請(qǐng)求,主進(jìn)程收到請(qǐng)求后向?yàn)g覽器發(fā)送進(jìn)程運(yùn)行情況。網(wǎng)頁(yè)通過(guò)自動(dòng)刷新不斷更新數(shù)據(jù)。
#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; //進(jìn)程A完成標(biāo)志
char flagB=FALSE; //進(jìn)程B完成標(biāo)志
int flagC=1; //進(jìn)程C完成標(biāo)志 1:未開始 2:已開始 3:已結(jié)束
int flagCount=0; //進(jìn)程C建立標(biāo)志
//進(jìn)程A信號(hào)處理
void endofA(int sig)
{
if(sig==SIGUSR1)
{
flagA=TRUE;
printf("修改了A\n");
}
return;
}
//進(jìn)程B信號(hào)處理
void endofB(int sig)
{
if(sig==SIGUSR2)
{
flagB=TRUE;
printf("修改了B\n");
}
return;
}
//進(jìn)程C信號(hào)處理
void endofC(int sig)
{
if(sig==SIGINT)
{
flagB=3;
printf("修改了C\n");
}
return;
}
int main(int argc,char *argv[])
{
int fdA[2],n; //父進(jìn)程與A進(jìn)程通信管道
char stateA[50]="子進(jìn)程A執(zhí)行中";
char stateB[50]="子進(jìn)程B執(zhí)行中";
char stateC[50]="子進(jìn)程B執(zhí)行中";
char temp[5];
pipe(fdA);
int fdB[2]; //父進(jìn)程與B進(jìn)程通信管道
pipe(fdB);
int server_socket = socket(AF_INET, SOCK_STREAM, 0); //服務(wù)器socket
struct sockaddr_in server_addr; //服務(wù)器地址
memset(&server_addr, 0, sizeof(server_addr)); //清空服務(wù)器地址
server_addr.sin_family = AF_INET; //IPv4 網(wǎng)絡(luò)協(xié)議的套接字類型
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) //進(jìn)程A
{
close(fdA[0]);
int runtime;
struct timeval start,end;
n=gettimeofday(&start, NULL);
gettimeofday(&end, NULL);
//空跑300秒,每3秒向管道內(nèi)寫入已運(yùn)行時(shí)間
//采用網(wǎng)頁(yè)顯示,主進(jìn)程與A之間有480個(gè)像素,故速度為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));
}
//向父進(jìn)程發(fā)送信號(hào)
if(kill(getppid(),SIGUSR1)==-1)
{
printf("process A send fail");
exit(0);
}
}
else
{
pid_t pidB;
pidB=fork();
//B進(jìn)程
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秒向管道內(nèi)寫入已運(yùn)行時(shí)間
//采用網(wǎng)頁(yè)顯示,主進(jìn)程與A之間有480個(gè)像素,故速度為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));
}
//向父進(jìn)程發(fā)送信號(hào)
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是否運(yùn)行完畢
if(flagA==TRUE&&flagB==TRUE&&flagC!=3&&flagCount==0)
{
flagC=2;
pipe(fdC);
pid_t pidC;
pidC=fork();
flagCount=1;
//C進(jìn)程
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秒向管道內(nèi)寫入已運(yùn)行時(shí)間
//采用網(wǎng)頁(yè)顯示,主進(jìn)程與A之間有180個(gè)像素,故速度為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);
}
//向父進(jìn)程發(fā)送信號(hào)
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,"子進(jìn)程A執(zhí)行完畢");
}
char readB[20];
if(!flagB)
{
read(fdB[0],readB,20);
strcpy(widthB,readB);
}
else{
strcpy(widthB,"480");
strcpy(stateB,"子進(jìn)程B執(zhí)行完畢");
}
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,"子進(jìn)程C執(zhí)行中");
}
else
{
strcpy(widthC,"180");
strcpy(stateC,"子進(jìn)程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>多進(jìn)程并發(fā)可視化</title></head><body><div style='height:250px;width:50px;background-color: red;'>父進(jìn)程</div><div style='height:8px;width:0px;background-color: #00ff2f;position: absolute;left: 60px;top: 50px;'>子進(jìn)程A執(zhí)行進(jìn)度</div><div style='height:8px;width:0px;background-color: #00ff2f;position: absolute;left: 60px;top: 200px;'>子進(jìn)程B執(zhí)行進(jìn)度</div><div style='height:100px;width:50px;background-color: #00ff2f;position: absolute;left: 530px;top: 0px;'>子進(jìn)程A</div><div style='height:100px;width:50px;background-color: #000dff;position: absolute;left: 530px;top: 150px;'>子進(jìn)程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;'>子進(jìn)程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>多進(jìn)程并發(fā)可視化</title></head><body><div style='height:250px;width:50px;background-color: red;'>父進(jìn)程</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;'>子進(jìn)程A</div><div style='height:100px;width:50px;background-color: #000dff;position: absolute;left: 530px;top: 150px;'>子進(jìn)程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;'>子進(jìn)程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;
}
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。