我在我的程序中執行一些物理計算,其中輸出需要存儲到臨時緩衝區並通過管道。如何在C中創建臨時緩衝區?
緩衝區需要共享不同的數據類型:首先,我需要存儲我研究這一課題的名稱;其次是我的計算結果(全部爲float
數字)。
的代碼看起來是這樣的:
initialdata.dat
Aston Martin Vantage V12|07.7|090
Ferrari LaFerrari |09.6|111
Lamborghini Aventador |09.6|097
Porsche 911 Turbo S |09.6|092
Tesla Model S P100D |10.0|069
Hennessey Venom GT |10.3|120
Bugatti Chiron |11.2|114
Koenigsegg Agera |10.3|121
MAIN.C:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <string.h>
#include <time.h>
#include <math.h>
#define READ 0
#define WRITE 1
#define M 2 // Number of subjects.
int main(){
int pipeToChild[2];
if (pipe(pipeToChild) < 0) {
fprintf(stderr,"Error in pipe!");
return -1;
}
pid_t pid[M];
srand (time(NULL));
// Declares the file pointer with the information.
FILE * pFile;
char buffer[34]; // Buffer where subject info is sent to childs.
char tempBuffer[50]; // The buffer that causes problems.
pFile = fopen ("initialdata.dat","r");
for(int i = 0; i < M; i++){
pid[i] = fork();
if (pid[i] < 0){
printf("Fork error!\n");
return -1;
}
else if(pid[i]==0){
// Creates the pipes (one per child) to pass the temporary buffer to the results process (still not created).
int pipeToResults[2];
if (pipe(pipeToResults) < 0) {
fprintf(stderr,"Error in pipe!");
return -1;
}
// Receives the car information from the file through a pipe.
char receivedValue[34];
receivedValue[33] = '\0';
close(pipeToChild[WRITE]);
read(pipeToChild[READ], receivedValue, sizeof(receivedValue));
// Processes the information and tokenizes it.
char name[25];
char CHARacceleration[6];
char CHARmaxSpeed[4];
strcpy(name, strtok(receivedValue, "|"));
strcpy(CHARacceleration, strtok(NULL, "|"));
strcpy(CHARmaxSpeed, strtok(NULL, "|"));
float acceleration = atof(CHARacceleration);
float maxSpeed = atoi(CHARmaxSpeed);
// Adds 0.0X to acceleration.
float randomNum = rand() % 5;
acceleration = acceleration + randomNum/100;
float distance = 0;
float TA = 0; // Time using Uniformly Accelerated Linear Motion.
float TB = 0; // Time using Linear Motion.
float TE = 0.5; // Time increment.
float currentVelocity = 0; // In m/s.
// Applies different physical calculations depending on the case.
while (distance <= 1000){
TA += TE;
if (currentVelocity < maxSpeed){ // Acceleration > 0
distance = (acceleration*pow((TA),2))/2;
currentVelocity = acceleration*TA;
distance = 2*distance;
}
else{ // Acceleration = 0
TB += TE;
currentVelocity = maxSpeed;
distance += maxSpeed*TB;
}
}
// Debug purposes, just for ensuring everything gets processed the right way.
printf("Name: %s\n", name);
printf("Distance: %.2f m\n", distance);
printf("Time: %.2f s\n", TA+TB);
printf("Max speed reached: %.2f km/h\n", currentVelocity*3.6);
printf("Acceleration: %.2f m/s^2\n", acceleration);
printf("\n");
// Comment this if you want to switch between the situations I talked about.
sprintf(tempBuffer, "%s %.2f %.2f %.2f %.2f", name, distance, TA+TB, currentVelocity, acceleration);
printf("Buffer: %s\n\n", tempBuffer);
exit(0);
}
else if(pid[i]>0){
// Generates a random subject from the list. Buggy section, fixed it the best way I could.
int randCar = rand() % 15 + 1;
if (randCar % 2 == 0)
randCar--;
for (int i = 1; i <= randCar; i++){
if (pFile != NULL)
fgets (buffer, sizeof(buffer), pFile);
else
perror ("ERROR reading file!");
}
char toSend[34]; //This will be passed through the `pipeToChild` pipe.
strcpy(toSend, buffer);
// Loads pipe.
close(pipeToChild[READ]);
write(pipeToChild[WRITE], toSend, strlen(toSend));
close(pipeToChild[WRITE]);
}
}
for (int i=0;i<M;i++){
waitpid(pid[i], NULL, 0);
}
fclose(pFile);
return 0;
}
輸出,雖然是不同的取決於如果我使用或者不是sprintf
。例如,對於M = 2,輸出應該是:
案例1:沒有sprintf
:
I'm the child process 1 with PID 12304
Name: Bugatti Chiron
Distance: 1012.61 m
Time: 9.50 s
Max speed reached: 383.72 km/h
Aceleration: 11.22 m/s^2
I'm the child process 2 with PID 12305
Name: Bugatti Chiron
Distance: 1012.61 m
Time: 9.50 s
Max speed reached: 383.72 km/h
Aceleration: 11.22 m/s^2
案例2:sprintf
:
I'm the child process 2 with PID 12307
I'm the child process 1 with PID 12306
Name: Bugatti Chiron
Distance: 1012.61 m
Time: 9.50 s
Max speed reached: 383.72 km/h
Aceleration: 11.22 m/s^2
Buffer: Bugatti Chiron 1012.61 9.50 383.82 11.22
有什麼問題「衝刺」?爲什麼這條線將整個程序搞砸了?
編輯:該程序是一個簡單的飆車模擬器,其中M車在1000米的直線競爭。所述master
過程創建m個隨機汽車(該功能未正確實施,雖然)和通過單個管通過存儲在.dat文件到M子進程的一些數據。
每一輛車都是一個子進程,它是在它那裏計算製成。一旦我們得到的值,每一個孩子通過自身的管到一個results
的過程,將它們存儲在輸出文件通過存儲在臨時緩衝區中的數據。請注意,此功能仍未實現,因爲首先我需要管理創建緩衝區。我的問題是只有關於緩衝區問題。
沒有[最小,**完整**和可驗證示例](http:// stackoverflow。com/help/mcve)它很難說任何具體的東西,我們所能做的只是猜測*(可能猜得不好)。並請[請閱讀如何提出良好問題](http://stackoverflow.com/help/how-to-ask)。 –
猜測雖然:這是因爲你無法控制調度程序的進程,並且額外的'sprintf'調用可能會導致調度程序意外切換進程?與輸出緩衝一起可能導致多進程程序中的輸出問題。 –
帶有註釋'// printf'的'...'很可能是一個問題。如果您調用'printf'並且不刷新輸出緩衝區,然後調用fork,則將獲得重複的輸出。嘗試在循環結尾添加一個'flush'。 –