bendour
bendour

Reputation: 61

c program loop in fork doesn't stop

I am simulating F1 training. I am using fork() and shared memory between processes.

  1. I am generating a random time for the cars that need to run for 5,400,000. I fork() for each car. the sons must simulate the generation of times. the father takes care of the display, he also makes a system ("clear") with a sleep (1) to slow down the display.

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

Answers (1)

ikegami
ikegami

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

Related Questions