私のプログラムでは、出力を一時バッファに格納しパイプを通過させる必要があるいくつかの物理計算を行っています。Cで一時バッファを作成するにはどうしたらいいですか?
バッファは異なるデータ型を共有する必要があります。まず、私が勉強している対象の名前を格納する必要があります。第二に私の計算の結果(すべてfloat
数字)。
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の initialdata.dat:
コードは次のようになります
#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
に問題は何「スプリント」?なぜこの線はプログラム全体をねじ込んでいるのですか?
EDIT:このプログラムは、M台の車が1000mの直線で競争する単純なドラッグレーシングシミュレータです。 master
プロセスはM個のランダムな車を作成しますが(この機能は正しく実装されていません)、の単一パイプを介して.datファイルに保存されたデータをM個の子プロセスに渡します。
すべての車は、子プロセスであり、計算が行われる場所にあります。値を取得すると、すべての子は、自身のパイプ~ というプロセスを介して、一時ファイルに格納されたデータを出力ファイルに格納します。最初にバッファを作成する必要があるため、この関数は実装されていないことに注意してください。私の質問は、のみですバッファの問題についてです。
[最小、**完全**、および検証可能な例](http:// stackoverflow。com/help/mcve)それは具体的なことを言うのが非常に難しくなります。我々ができるのは*推測*です(おそらくひどく推測されます)。そして、[良い質問をする方法について](http://stackoverflow.com/help/how-to-ask)を読んでください。 –
しかし、それはスケジューラの処理を制御できないためです。追加の 'sprintf'呼び出しによって、スケジューラが予期せずプロセスを切り替える可能性がありますか?これは、出力バッファリングと一緒に、マルチプロセスプログラムで出力の問題を引き起こす可能性があります。 –
コメント '// printf'を持つ' ... 'は非常に問題になりそうです。 'printf'を呼び出して出力バッファをフラッシュせずにforkを呼び出すと、出力が重複します。ループの最後に 'flush'を追加してみてください。 –