Reputation: 61
I am simulating F1 training. I am using fork() and shared memory between processes.
but the program does not stop despite the 5,400,000 limit. The program lasts more than 20min without stopping! I would like it to generate the display a number of times and stop!
Thank you.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <sys/wait.h>
#define NUMBER_OF_CARS 20
#define MIN 25000 // time generator
#define MAX 40000
int numeroVoiture[NUMBER_OF_CARS] = {44, 77, 11, 33, 3, 4, 5, 18, 14, 31, 16, 55, 10, 22, 7, 99, 9, 47, 6, 63};
typedef struct {
unsigned int id;
unsigned int s1;
unsigned int s2;
unsigned int s3;
unsigned int best_S1;
unsigned int best_S2;
unsigned int best_S3;
unsigned int tempsTotal;
unsigned int best_Circuit;
unsigned int lap;
unsigned int compteurStand;
unsigned int out;
} voiture;
voiture *shared_memory;
voiture copyTableau[NUMBER_OF_CARS];
int faireDesTours(int i);
unsigned int generateNumber(void);
void afficherTableau(void);
int compare (const void * a, const void * b);
void initVoiture(int i);
void sortLap(void);
int main(void)
{
/***************************************************
* Creating shared memory *
****************************************************/
int segment_id = shmget(IPC_PRIVATE, sizeof(voiture) * NUMBER_OF_CARS, 0666 | IPC_CREAT);
if (segment_id == -1) {
perror("shmget() failed !");
exit(EXIT_FAILURE);
}
shared_memory = shmat(segment_id, NULL, 0);
if (shared_memory == (void *) (-1)) {
perror("shmat() failed !");
exit(EXIT_FAILURE);
}
/**********************************************************
* Creation of child / cars *
**********************************************************/
for (int i = 0; i < NUMBER_OF_CARS; ++i)
{
/******** problem fork *********/
pid_t pid = fork();
if (pid == -1) {
perror("fork failed !");
exit(EXIT_FAILURE);
}
/******** child *********/
if(pid == 0) {
shared_memory[i].id = numeroVoiture[i]; //each car has a number
faireDesTours(i); //5400000
}
/******** father *********/
else {
wait(NULL);
system("clear");
// copy of array
memcpy( copyTableau, shared_memory, sizeof(copyTableau) );
//trier Tableau;
qsort( copyTableau, NUMBER_OF_CARS, sizeof(voiture), compare );
sortLap();
afficherTableau();
sleep(1);
}
}
/******** Detach memory segments *********/
shmdt(shared_memory);
/******** Delete shared memory *********/
shmctl(segment_id, IPC_RMID, NULL);
exit(EXIT_SUCCESS);
}
unsigned int tempsMaxCircuit = 5400000;
int faireDesTours( int i ) {
initVoiture(i);
unsigned int tour_complet;
while (shared_memory[i].tempsTotal <= tempsMaxCircuit) //no exceeded time
{
tour_complet = 0;
srand(time(NULL) + getpid());
/* **** S1 **** */
shared_memory[i].s1 = generateNumber();
if (shared_memory[i].s1 < shared_memory[i].best_S1) {
shared_memory[i].best_S1 = shared_memory[i].s1;
}
shared_memory[i].tempsTotal += shared_memory[i].s1;
tour_complet += shared_memory[i].s1;
/* *************************************** */
if (shared_memory[i].tempsTotal >= tempsMaxCircuit)
{
break;
}
/* **** S2 **** */
shared_memory[i].s2 = generateNumber();
if (shared_memory[i].s2 < shared_memory[i].best_S2) {
shared_memory[i].best_S2 = shared_memory[i].s2;
}
shared_memory[i].tempsTotal += shared_memory[i].s2;
tour_complet += shared_memory[i].s2;
/* *************************************** */
if (shared_memory[i].tempsTotal >= tempsMaxCircuit)
{
break;
}
/* **** S3 **** */
shared_memory[i].s3 = generateNumber();
if (shared_memory[i].s3 < shared_memory[i].best_S3) {
shared_memory[i].best_S3 = shared_memory[i].s3;
}
shared_memory[i].tempsTotal += shared_memory[i].s3;
tour_complet += shared_memory[i].s3;
/* *************************************** */
/* **** Best Time Circuit **** */
if (tour_complet < shared_memory[i].best_Circuit) {
shared_memory[i].best_Circuit = tour_complet;
shared_memory[i].best_Circuit = tour_complet;
}
/* *************************************** */
}
return 0;
}
unsigned int generateNumber(void)
{
return rand()%(MAX-MIN+1)+MIN;
}
void afficherTableau(void) { // Display
printf("\n\tBest times per complete lap\n");
printf(" ===================================================================================\n");
printf(" | ID | s1 | s2 | s3 | Tour | LAP |\n");
printf(" |==================================================================================\n");
for (int i = 0; i < NUMBER_OF_CARS; i++){
printf(" | %2d | %5d | %5d | %5d | %6d | %5d |\n", \
copyTableau[i].id, \
copyTableau[i].s1, copyTableau[i].s2, copyTableau[i].s3, \
copyTableau[i].best_Circuit,\
copyTableau[i].lap);
}
printf(" ===================================================================================\n\n");
}
// function sort
int compare(const void * a, const void * b)
{
voiture *voitureA = (voiture *)a;
voiture *voitureB = (voiture *)b;
return ( voitureA->best_Circuit - voitureB->best_Circuit );
}
// init each structure value of car
void initVoiture(int i) {
shared_memory[i].s1 = 0;
shared_memory[i].s2 = 0;
shared_memory[i].s3 = 0;
shared_memory[i].best_S1 = MAX;
shared_memory[i].best_S2 = MAX;
shared_memory[i].best_S3 = MAX;
shared_memory[i].best_Circuit = 3 * MAX;
shared_memory[i].tempsTotal = 0;
shared_memory[i].lap = 0;
shared_memory[i].compteurStand = 0;
shared_memory[i].out = false;
}
void sortLap(void) {
unsigned int difference;
for (int i = 1; i < NUMBER_OF_CARS; i++)
{
difference = ( copyTableau[i].best_Circuit - copyTableau[i - 1].best_Circuit );
copyTableau[i].lap = difference;
}
}
Upvotes: 0
Views: 46
Reputation: 386706
At the core, you have
for (int i = 0; i < NUMBER_OF_CARS; ++i)
{
/******** problem fork *********/
pid_t pid = fork();
if (pid == -1) {
perror("fork failed !");
exit(EXIT_FAILURE);
}
/******** child *********/
if(pid == 0) {
...
}
/******** father *********/
else {
wait(NULL);
...
}
}
You're missing a call to exit
in the child. Without this, each child loops around and starts creating children of its own. It will eventually end, but not after creating a huge number of processes unintentionally.
By the way, it's kind of weird to create a child if the first thing the parent does is wait for the child to end.
Upvotes: 2