我在我的程序中执行一些物理计算,其中输出需要存储到临时缓冲区并通过管道。如何在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'。 –